/* Written by David MacKenzie . */ #include "system.h" #include "error.h" #include "progname.h" #include #include #include #include #include /* If |NULL|, error will flush |stdout|, then print on |stderr| the program name, a colon and a space. Otherwise, error will call this function without parameters instead. */ void (*error_print_progname)(void); /* This variable is incremented each time |error| is called. */ unsigned int error_message_count; /* Return non-zero if |fd| is open. */ static int is_open(int fd) { return 0 <= fcntl(fd, F_GETFL); } static void flush_stdout(void) { if (is_open(1)) fflush(stdout); } static void print_errno_message(int errnum) { char const *s; char errbuf[1024]; if (strerror_r(errnum, errbuf, sizeof errbuf) == 0) s = errbuf; else s = 0; if (!s) s = "Unknown system error"; fprintf(stderr, ": %s", s); } static void error_tail(int status, int errnum, const char *message, va_list args) { vfprintf(stderr, message, args); va_end (args); ++error_message_count; if (errnum) print_errno_message(errnum); putc ('\n', stderr); fflush(stderr); if (status) exit(status); } /* Print the program name and error message |message|, which is a printf-style format string with optional args. If |errnum| is nonzero, print its corresponding system error message. Exit with status |status| if it is nonzero. */ void error(int status, int errnum, const char *message, ...) { va_list args; flush_stdout(); if (error_print_progname) (*error_print_progname)(); else { fprintf(stderr, "%s: ", get_program_name()); } va_start (args, message); error_tail(status, errnum, message, args); }