diff --git a/src/include/pv.h b/src/include/pv.h index 031f1c2..131f989 100644 --- a/src/include/pv.h +++ b/src/include/pv.h @@ -180,7 +180,7 @@ void pv_nanosleep(long long); /* * Set the prefix (program name) for any PV error messages. */ -extern void pv_set_error_prefix(/*@unique@ */ const char *); +extern void pv_set_error_prefix(/*@null@ */ const char *); /* * Create a new state structure, and return it, or 0 (NULL) on error. diff --git a/src/main/main.c b/src/main/main.c index 2b983bf..8ba8c0e 100644 --- a/src/main/main.c +++ b/src/main/main.c @@ -707,6 +707,7 @@ int main(int argc, char **argv) fprintf(stderr, "%s: %s: %s\n", opts->program_name, _("state allocation failed"), strerror(errno)); opts_free(opts); debug("%s: %d", "exiting with status", PV_ERROREXIT_MEMORY); + pv_set_error_prefix(NULL); return PV_ERROREXIT_MEMORY; /*@+mustfreefresh@ */ } @@ -720,6 +721,7 @@ int main(int argc, char **argv) if (0 != pidfile_rc) { pv_state_free(state); opts_free(opts); + pv_set_error_prefix(NULL); return pidfile_rc; } } @@ -732,6 +734,7 @@ int main(int argc, char **argv) if (!opts_add_file(opts, "-")) { pv_state_free(state); opts_free(opts); + pv_set_error_prefix(NULL); return PV_ERROREXIT_MEMORY; } } @@ -817,6 +820,7 @@ int main(int argc, char **argv) if (0 != retcode) { pv_state_free(state); opts_free(opts); + pv_set_error_prefix(NULL); return retcode; } @@ -867,6 +871,7 @@ int main(int argc, char **argv) pv_sig_fini(state); pv_state_free(state); opts_free(opts); + pv_set_error_prefix(NULL); return retcode; } /* As above - no ETA if the size is unknown. */ @@ -974,6 +979,9 @@ int main(int argc, char **argv) /* Free the data from parsing the command-line arguments. */ opts_free(opts); + /* Clear the error message prefix. */ + pv_set_error_prefix(NULL); + debug("%s: %d", "exiting with status", retcode); return retcode; diff --git a/src/pv/display.c b/src/pv/display.c index 2538dac..c933a92 100644 --- a/src/pv/display.c +++ b/src/pv/display.c @@ -50,41 +50,30 @@ #endif /* - * The error prefix for messages (the program name); whether it has been - * set; and whether any output has been displayed yet, indicating whether - * any errors must be preceded by a newline. + * The error prefix for messages (the program name); and whether any output + * has been displayed yet, indicating whether any errors must be preceded by + * a newline. */ -/* TODO: make pv__error_prefix a dynamic buffer. */ -static char pv__error_prefix[64]; /* flawfinder: ignore */ -static bool pv__error_prefix_set = false; +/*@only@ */ static /*@null@ */ char * pv__error_prefix = NULL; static bool pv__output_produced = false; -/* - * flawfinder rationale: zeroed before use, string copy is bounded to 1 less - * than size so it always has \0 termination. Not used unless initialised, - * by checking pv__error_prefix_set. - */ /* - * Set the error message prefix. + * Set the error message prefix. If the new prefix is NULL, the current + * prefix is cleared. */ -void pv_set_error_prefix( /*@unique@ */ const char *prefix) +void pv_set_error_prefix( /*@null@ */ const char *prefix) { + if (NULL != pv__error_prefix) { + free(pv__error_prefix); + pv__error_prefix = NULL; + } if (NULL == prefix) return; - memset(pv__error_prefix, 0, sizeof(pv__error_prefix)); - strncpy(pv__error_prefix, prefix, sizeof(pv__error_prefix) - 1); /* flawfinder: ignore */ - pv__error_prefix_set = true; - /* - * flawfinder rationale: strncpy's pointers are as valid as they can - * be since the first is a static buffer and the second is - * caller-supplied. The caller must \0-terminate the string but in - * any case it is bounded to 1 less than the size of the - * destination. The destination is zeroed before use so the result - * is guaranteed to be \0-terminated. - */ + pv__error_prefix = pv_strdup(prefix); } + /* * Output an error message. If anything has been sent to the terminal * already, then put a newline before the message, to avoid writing over @@ -95,7 +84,7 @@ void pv_error(char *format, ...) va_list ap; if (pv__output_produced) fprintf(stderr, "\n"); - if (pv__error_prefix_set) + if (NULL != pv__error_prefix) fprintf(stderr, "%s: ", pv__error_prefix); va_start(ap, format); (void) vfprintf(stderr, format, ap); /* flawfinder: ignore */