diff --git a/src/xspice/icm/digital/d_process/cfunc.mod b/src/xspice/icm/digital/d_process/cfunc.mod index 91c467f19..7fe08d9ae 100644 --- a/src/xspice/icm/digital/d_process/cfunc.mod +++ b/src/xspice/icm/digital/d_process/cfunc.mod @@ -80,9 +80,9 @@ MODIFICATIONS For Windows VisualC and Mingw the pipes use binary mode, and named pipes or fifos are not supported. - 13 October 2023 Brian Taylor - Avoid calling exit(1) after reporting an error to stderr. Use - cm_message_send. + 14 October 2023 Brian Taylor + Use cm_message_send() to report errors, avoid exit(1) calls. + REFERENCED FILES @@ -99,7 +99,6 @@ REFERENCED FILES #include #include #include -#include #endif #include @@ -112,53 +111,16 @@ typedef unsigned char uint8_t; typedef struct { int pipe_to_child; int pipe_from_child; - int start_failed; - int header_failed; - int exchange_failed; uint8_t N_din, N_dout; // number of inputs/outputs bytes Digital_State_t dout_old[256]; // max possible storage to track output changes } Process_t; #if defined(_MSC_VER) || defined(__MINGW64__) #include -static unsigned int w_start(char *system_command, const char *const *argv, Process_t * process); +static int w_start(char *system_command, const char *const *argv, Process_t * process); #endif -static void report_sendheader_message(unsigned int msg_num) -{ - static char *messages[] = { - "", - "ERROR: d_process supports max 255 input and max 255 output signals", - "ERROR: d_process when sending header", - "ERROR: d_process didn't respond to the header", - "ERROR: d_process returned invalid header version", - "ERROR: d_process header I/O mismatch N_din and N_dout counts" - }; - cm_message_send(messages[msg_num]); -} - -static void report_exchangedata_message(unsigned int msg_num) -{ - static char *messages[] = { - "", - "ERROR: d_process when writing exchange data", - "ERROR: d_process received invalid dout count when reading exchange data" - }; - cm_message_send(messages[msg_num]); -} - -static void report_start_message(unsigned int msg_num) -{ - static char *messages[] = { - "", - "ERROR: d_process process_file argument is invalid or not given", - "ERROR: d_process failed to open pipe", - "ERROR: d_process failed to fork or start process" - }; - cm_message_send(messages[msg_num]); -} - -static unsigned int sendheader(Process_t * process, int N_din, int N_dout) +static int sendheader(Process_t * process, int N_din, int N_dout) { #if defined(_MSC_VER) #pragma pack(push, 1) @@ -173,6 +135,7 @@ static unsigned int sendheader(Process_t * process, int N_din, int N_dout) #endif if (N_din > 255 || N_dout > 255) { + cm_message_send("Error: d_process supports max 255 input and output and 255 output signals"); return 1; } @@ -181,7 +144,8 @@ static unsigned int sendheader(Process_t * process, int N_din, int N_dout) #else if (write(process->pipe_to_child, &header, sizeof(header)) == -1) { #endif - return 2; + cm_message_send("Error: d_process when sending header"); + return 1; } // Wait for echo which must return the same header to ack transfer @@ -190,13 +154,17 @@ static unsigned int sendheader(Process_t * process, int N_din, int N_dout) #else if (read(process->pipe_from_child, &header, sizeof(header)) != sizeof(header)) { #endif - return 3; + cm_message_send("Error: d_process didn't respond to the header"); + return 1; } if (header.version != D_PROCESS_FORMAT_VERSION) { - return 4; + cm_message_printf("Error: d_process returned invalid version: %d", header.version); + return 1; } if (header.N_din != N_din || header.N_dout != N_dout) { - return 5; + cm_message_printf("Error: d_process I/O mismatch: in %d vs. returned %d, out %d vs. returned %d", + N_din, header.N_din, N_dout, header.N_dout); + return 1; } process->N_din = (uint8_t)DLEN(N_din); @@ -205,7 +173,7 @@ static unsigned int sendheader(Process_t * process, int N_din, int N_dout) } -static unsigned int dprocess_exchangedata(Process_t * process, double time, uint8_t din[], uint8_t dout[]) +static int dprocess_exchangedata(Process_t * process, double time, uint8_t din[], uint8_t dout[]) { #if defined(_MSC_VER) #pragma pack(push, 1) @@ -236,6 +204,7 @@ static unsigned int dprocess_exchangedata(Process_t * process, double time, uint wlen = write(process->pipe_to_child, &packet, sizeof(double) + process->N_din); #endif if (wlen == -1) { + cm_message_send("Error: d_process when writing exchange data"); return 1; } @@ -244,14 +213,17 @@ static unsigned int dprocess_exchangedata(Process_t * process, double time, uint #else if (read(process->pipe_from_child, dout, process->N_dout) != process->N_dout) { #endif - return 2; + cm_message_printf( + "Error: d_process received invalid dout count, expected %d", + process->N_dout); + return 1; } return 0; } #if !defined(_MSC_VER) && !defined(__MINGW64__) -static unsigned int start(char *system_command, char * c_argv[], Process_t * process) +static int start(char *system_command, char * c_argv[], Process_t * process) { int pipe_to_child[2]; int pipe_from_child[2]; @@ -259,6 +231,7 @@ static unsigned int start(char *system_command, char * c_argv[], Process_t * pro size_t syscmd_len = strlen(system_command); if (syscmd_len == 0) { + cm_message_send("Error: d_process process_file argument is not given"); return 1; } if (system_command[syscmd_len-1] == '|') { @@ -272,20 +245,20 @@ static unsigned int start(char *system_command, char * c_argv[], Process_t * pro strncpy(filename_out, system_command, syscmd_len-1); strcpy(&filename_out[syscmd_len-1], "_out"); if ((process->pipe_to_child = open(filename_in, O_WRONLY)) == -1) { - return 2; + cm_message_send("Error: d_process failed to open in fifo"); + return 1; } if ((process->pipe_from_child = open(filename_out, O_RDONLY)) == -1) { - return 2; + cm_message_send("Error: d_process failed to open out fifo"); + return 1; } if (filename_in) free(filename_in); if (filename_out) free(filename_out); } else { - if (pipe(pipe_to_child) || pipe(pipe_from_child)) { - return 2; - } - if ((pid=fork()) ==-1) { - return 3; + if (pipe(pipe_to_child) || pipe(pipe_from_child) || (pid=fork()) ==-1) { + cm_message_send("Error: d_process cannot create pipes and fork"); + return 1; } if (pid == 0) { dup2(pipe_to_child[0],0); @@ -295,11 +268,12 @@ static unsigned int start(char *system_command, char * c_argv[], Process_t * pro if (execv(system_command, c_argv) == -1) { fprintf(stderr, - "ERROR: d_process failed to fork or start process %s\n", + "Error: d_process failed to fork or start process %s\n", system_command); - return 3; + exit(1); } - } else { + } + else { process->pipe_to_child = pipe_to_child[1]; process->pipe_from_child = pipe_from_child[0]; close(pipe_to_child[0]); @@ -325,19 +299,10 @@ static void cm_d_process_callback(ARGS, Mif_Callback_Reason_t reason) } } -static int any_failed(Process_t *p) -{ - if (p->start_failed || p->header_failed || p->exchange_failed) { - return 1; - } else { - return 0; - } -} void cm_d_process(ARGS) { int i; /* generic loop counter index */ - unsigned int errnum; Digital_State_t *reset, /* storage for reset value */ *reset_old; /* previous reset value */ @@ -378,23 +343,11 @@ void cm_d_process(ARGS) #undef C_ARGV_SIZE #if defined(_MSC_VER) || defined(__MINGW64__) - errnum = w_start(c_argv[0], (const char *const *)c_argv, local_process); + (void) w_start(c_argv[0], (const char *const *)c_argv, local_process); #else - errnum = start(c_argv[0], c_argv, local_process); + (void) start(c_argv[0], c_argv, local_process); #endif - if (errnum) { - report_start_message(errnum); - local_process->start_failed = 1; - return; - } - if (any_failed(local_process)) return; - errnum = sendheader(local_process, PORT_SIZE(in), PORT_SIZE(out)); - if (errnum) { - report_sendheader_message(errnum); - local_process->header_failed = 1; - return; - } - if (any_failed(local_process)) return; + (void) sendheader(local_process, PORT_SIZE(in), PORT_SIZE(out)); for (i=0; i> 3] |= (uint8_t)(b << (i & 7)); } - errnum = dprocess_exchangedata(local_process, (ONE != *reset) ? TIME : -TIME, din, dout); - if (errnum) { - report_exchangedata_message(errnum); - local_process->exchange_failed = 1; - return; - } + (void) dprocess_exchangedata(local_process, (ONE != *reset) ? TIME : -TIME, din, dout); for (i=0; i> 3] >> (i & 7)) & 0x01) ? ONE : ZERO; @@ -494,7 +440,7 @@ void cm_d_process(ARGS) #include #include -static unsigned int w_start(char *system_command, const char *const *argv, Process_t * process) +static int w_start(char *system_command, const char *const *argv, Process_t * process) { int pipe_to_child[2]; int pipe_from_child[2]; @@ -502,14 +448,21 @@ static unsigned int w_start(char *system_command, const char *const *argv, Proce int mode = _O_BINARY; size_t syscmd_len = strlen(system_command); - if (syscmd_len == 0 || system_command[syscmd_len-1] == '|') { + if (syscmd_len == 0) { + cm_message_send("Error: d_process process_file argument is not given"); + return 1; + } + if (system_command[syscmd_len-1] == '|') { + cm_message_send("Error: d_process named pipe/fifo not supported"); return 1; } if (_pipe(pipe_to_child, 1024, mode) == -1) { - return 2; + cm_message_send("Error: d_process failed to open pipe_to_child"); + return 1; } if (_pipe(pipe_from_child, 1024, mode) == -1) { - return 2; + cm_message_send("Error: d_process failed to open pipe_from_child"); + return 1; } _dup2(pipe_to_child[0],0); @@ -520,7 +473,8 @@ static unsigned int w_start(char *system_command, const char *const *argv, Proce _flushall(); pid = _spawnvp(_P_NOWAIT, system_command, argv); if (pid == -1) { - return 3; + cm_message_printf("Error: d_process failed to spawn %s", system_command); + return 1; } process->pipe_to_child = pipe_to_child[1];