static void verror_msg(int err_no, const char *fmt, va_list p)
{
+ char *msg;
+
fflush(NULL);
- fprintf(stderr, "%s: ", progname);
- vfprintf(stderr, fmt, p);
- if (err_no)
- fprintf(stderr, ": %s\n", strerror(err_no));
- else
- putc('\n', stderr);
- fflush(stderr);
+
+ /* We want to print entire message with single fprintf to ensure
+ * message integrity if stderr is shared with other programs.
+ * Thus we use vasprintf + single fprintf.
+ */
+ msg = NULL;
+ vasprintf(&msg, fmt, p);
+ if (msg) {
+ if (err_no)
+ fprintf(stderr, "%s: %s: %s\n", progname, msg, strerror(err_no));
+ else
+ fprintf(stderr, "%s: %s\n", progname, msg);
+ free(msg);
+ } else {
+ /* malloc in vasprintf failed, try it without malloc */
+ fprintf(stderr, "%s: ", progname);
+ vfprintf(stderr, fmt, p);
+ if (err_no)
+ fprintf(stderr, ": %s\n", strerror(err_no));
+ else
+ putc('\n', stderr);
+ }
+ /* We don't switch stderr to buffered, thus fprintf(stderr)
+ * always flushes its output and this is not necessary: */
+ /* fflush(stderr); */
}
void error_msg(const char *fmt, ...)