raw
vtools_genesis          1 /* Written by David MacKenzie <djm@gnu.ai.mit.edu>.  */
vtools_genesis 2
vtools_genesis 3 #include "system.h"
vtools_genesis 4 #include "error.h"
vtools_genesis 5 #include "progname.h"
vtools_genesis 6 #include <stdarg.h>
vtools_genesis 7 #include <stdio.h>
vtools_genesis 8 #include <stdlib.h>
vtools_genesis 9 #include <string.h>
vtools_genesis 10 #include <fcntl.h>
vtools_genesis 11
vtools_genesis 12 /* If |NULL|, error will flush |stdout|, then print on |stderr| the
vtools_genesis 13 program name, a colon and a space. Otherwise, error will call this
vtools_genesis 14 function without parameters instead. */
vtools_genesis 15 void (*error_print_progname)(void);
vtools_genesis 16
vtools_genesis 17 /* This variable is incremented each time |error| is called. */
vtools_genesis 18 unsigned int error_message_count;
vtools_genesis 19
vtools_genesis 20
vtools_genesis 21 /* Return non-zero if |fd| is open. */
vtools_genesis 22 static int
vtools_genesis 23 is_open(int fd) {
vtools_genesis 24 return 0 <= fcntl(fd, F_GETFL);
vtools_genesis 25 }
vtools_genesis 26
vtools_genesis 27 static void
vtools_genesis 28 flush_stdout(void) {
vtools_genesis 29 if (is_open(1))
vtools_genesis 30 fflush(stdout);
vtools_genesis 31 }
vtools_genesis 32
vtools_genesis 33 static void
vtools_genesis 34 print_errno_message(int errnum) {
vtools_genesis 35 char const *s;
vtools_genesis 36 char errbuf[1024];
vtools_genesis 37 if (strerror_r(errnum, errbuf, sizeof errbuf) == 0)
vtools_genesis 38 s = errbuf;
vtools_genesis 39 else
vtools_genesis 40 s = 0;
vtools_genesis 41 if (!s)
vtools_genesis 42 s = "Unknown system error";
vtools_genesis 43 fprintf(stderr, ": %s", s);
vtools_genesis 44 }
vtools_genesis 45
vtools_genesis 46 static void
vtools_genesis 47 error_tail(int status, int errnum, const char *message, va_list args) {
vtools_genesis 48 vfprintf(stderr, message, args);
vtools_genesis 49 va_end (args);
vtools_genesis 50
vtools_genesis 51 ++error_message_count;
vtools_genesis 52 if (errnum)
vtools_genesis 53 print_errno_message(errnum);
vtools_genesis 54 putc ('\n', stderr);
vtools_genesis 55 fflush(stderr);
vtools_genesis 56 if (status)
vtools_genesis 57 exit(status);
vtools_genesis 58 }
vtools_genesis 59
vtools_genesis 60
vtools_genesis 61 /* Print the program name and error message |message|, which is a
vtools_genesis 62 printf-style format string with optional args. If |errnum| is
vtools_genesis 63 nonzero, print its corresponding system error message. Exit with
vtools_genesis 64 status |status| if it is nonzero. */
vtools_genesis 65 void
vtools_genesis 66 error(int status, int errnum, const char *message, ...) {
vtools_genesis 67 va_list args;
vtools_genesis 68 flush_stdout();
vtools_genesis 69 if (error_print_progname)
vtools_genesis 70 (*error_print_progname)();
vtools_genesis 71 else {
vtools_genesis 72 fprintf(stderr, "%s: ", get_program_name());
vtools_genesis 73 }
vtools_genesis 74
vtools_genesis 75 va_start (args, message);
vtools_genesis 76 error_tail(status, errnum, message, args);
vtools_genesis 77 }
vtools_genesis 78