Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 54 additions & 44 deletions src/libnml/rcs/rcs_print.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include <string.h> /* strchr(), memmove() */
#include <stdlib.h> /* malloc(), free(), realloc() */
#include <errno.h> // errno()
#include <vector>

#include <sys/types.h>
#include <unistd.h> /* getpid() */
Expand All @@ -41,7 +42,6 @@ FILE *rcs_print_file_stream = NULL;
char rcs_print_file_name[80] = "rcs_out.txt";

char last_error_bufs[4][error_buf_size];
int error_bufs_initialized = 0;
int last_error_buf_filled = 0;

void set_rcs_print_destination(RCS_PRINT_DESTINATION_TYPE _dest)
Expand Down Expand Up @@ -260,6 +260,9 @@ use separate_words to parse the string followed by commands like strtod to
convert each word. */
int separate_words(char **_dest, int _max, char *_src)
{
// FIXME: This returns pointers into the static buffer in here.
// It is used in cms/cms.cc and cms/cns_cfg.cc. There it should be replaced
// with a proper reentrant string splitter function.
static char word_buffer[256];
int i;
if (NULL == _dest || NULL == _src) {
Expand All @@ -282,38 +285,35 @@ int separate_words(char **_dest, int _max, char *_src)

int rcs_vprint(const char *_fmt, va_list _args, int save_string)
{
static char temp_string[error_buf_size];

if (NULL == _fmt) {
return (EOF);
}
if (strlen(_fmt) > 200) { /* Might overflow temp_string. */
return (EOF);
return EOF;
}
if (EOF == (int) vsnprintf(temp_string, sizeof(temp_string), _fmt, _args)) {
return (EOF);
// Determine the required size of the buffer (see EXAMPLES in printf(3))
va_list va;
va_copy(va, _args); // Copy because we need to call vsnprintf twice
int sz = vsnprintf(NULL, 0, _fmt, va);
va_end(va);
if (sz < 0)
return EOF;
// Create the space and print into it
std::vector<char> tmpstr(sz+1);
if (vsnprintf(tmpstr.data(), sz+1, _fmt, _args) < 0) {
return EOF;
}
if (save_string) {
if (!error_bufs_initialized) {
memset(last_error_bufs[0], 0, 100);
memset(last_error_bufs[1], 0, 100);
memset(last_error_bufs[2], 0, 100);
memset(last_error_bufs[3], 0, 100);
error_bufs_initialized = 1;
}
last_error_buf_filled++;
last_error_buf_filled %= 4;
rtapi_strlcpy(last_error_bufs[last_error_buf_filled], temp_string, 99);
last_error_buf_filled++;
last_error_buf_filled %= 4;
rtapi_strlcpy(last_error_bufs[last_error_buf_filled], tmpstr.data(), error_buf_size-1);
}
return (rcs_fputs(temp_string));
return rcs_fputs(tmpstr.data());
}

int rcs_puts(const char *_str)
{
int retval, retval2;
retval = rcs_fputs(const_cast< char * >(_str));
retval = rcs_fputs(_str);
if (retval != EOF) {
retval2 = rcs_fputs(const_cast< char * >("\n"));
retval2 = rcs_fputs("\n");
if (retval2 != EOF) {
retval += retval;
} else {
Expand Down Expand Up @@ -423,17 +423,23 @@ int set_rcs_print_file(char *_file_name)

int rcs_print(const char *_fmt, ...)
{
static char temp_buffer[400];
int retval;
va_list args;
// Determine the required size of the buffer (see EXAMPLES in printf(3))
va_start(args, _fmt);
retval = vsnprintf(temp_buffer, sizeof(temp_buffer), _fmt, args);
int sz = vsnprintf(NULL, 0, _fmt, args);
va_end(args);
if (retval == (EOF)) {
return EOF;
}
retval = rcs_fputs(temp_buffer);
return (retval);
if (sz < 0)
return -1;

// Create the space and print into it
std::vector<char> tmpbuf(sz+1);
va_start(args, _fmt);
sz = vsnprintf(tmpbuf.data(), sz+1, _fmt, args);
va_end(args);
if (sz < 0)
return -1;

return rcs_fputs(tmpbuf.data());
}

#ifndef DO_NOT_USE_RCS_PRINT_ERROR_NEW
Expand Down Expand Up @@ -502,22 +508,26 @@ void clear_rcs_print_flag(long flag_to_clear)

int rcs_print_sys_error(int error_source, const char *_fmt, ...)
{
static char temp_string[256];
static char message_string[512];
va_list args;
int r;

if (NULL == _fmt) {
return (EOF);
}
if (strlen(_fmt) > 200) { /* Might overflow temp_string. */
return (EOF);
}

// Determine the required size of the buffer (see EXAMPLES in printf(3))
va_start(args, _fmt);
r = vsnprintf(temp_string, sizeof(temp_string), _fmt, args);
r = vsnprintf(NULL, 0, _fmt, args);
va_end(args);
if (r < 0) {
return EOF;
}

// Create the space and print into it
std::vector<char> tmpstr(r+1);
va_start(args, _fmt);
r = vsnprintf(tmpstr.data(), r+1, _fmt, args);
va_end(args);
if (r < 0) {
return EOF;
}
Expand All @@ -533,18 +543,18 @@ int rcs_print_sys_error(int error_source, const char *_fmt, ...)
}

switch (error_source) {
case ERRNO_ERROR_SOURCE:
snprintf(message_string, sizeof(message_string),
"%s %d %s\n", temp_string, errno,
strerror(errno));
rcs_puts(message_string);
case ERRNO_ERROR_SOURCE: {
r = snprintf(NULL, 0, "%s %d %s\n", tmpstr.data(), errno, strerror(errno));
std::vector<char> msgstr(r+1);
snprintf(msgstr.data(), r+1, "%s %d %s\n", tmpstr.data(), errno, strerror(errno));
r = rcs_puts(msgstr.data());
break;

}
default:
rcs_puts(temp_string);
r = rcs_puts(tmpstr.data());
break;
}
return (strlen(temp_string));
return r;
}

#ifdef rcs_print_error
Expand Down
Loading