From b6f37d7555a68392ea976621aa9d408efec75c9e Mon Sep 17 00:00:00 2001 From: James Y Knight Date: Mon, 22 Jul 2019 20:39:26 -0400 Subject: [PATCH] Add support for the glibc-specific error.h header. This includes the functions 'error', 'error_at_line', and their associated global variables. --- dynamic.list | 7 ++++ include/error.h | 23 +++++++++++++ src/legacy/error.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 110 insertions(+) create mode 100644 include/error.h create mode 100644 src/legacy/error.c diff --git a/dynamic.list b/dynamic.list index ee0d363b..d8f57b85 100644 --- a/dynamic.list +++ b/dynamic.list @@ -42,4 +42,11 @@ __progname; __progname_full; __stack_chk_guard; + +error_print_progname; +error_message_count; +error_one_per_line; +__error_print_progname; +__error_message_count; +__error_one_per_line; }; diff --git a/include/error.h b/include/error.h new file mode 100644 index 00000000..d4e7fad6 --- /dev/null +++ b/include/error.h @@ -0,0 +1,23 @@ +#ifndef _ERROR_H +#define _ERROR_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +extern void (*error_print_progname) (void); +extern unsigned int error_message_count; +extern int error_one_per_line; + +void error(int status, int errnum, const char *fmt, ...); +void error_at_line(int status, int errnum, + const char *file, unsigned int linenum, + const char *fmt, ...); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/legacy/error.c b/src/legacy/error.c new file mode 100644 index 00000000..2b820954 --- /dev/null +++ b/src/legacy/error.c @@ -0,0 +1,80 @@ +#include +#include +#include +#include +#include +#include "stdio_impl.h" +#include "libc.h" + +void (*__error_print_progname) (void) = 0; +unsigned int __error_message_count = 0; +int __error_one_per_line = 0; + +static unsigned int saved_linenum = 0; +static const char *saved_file = 0; + +static void errorv(int status, int errnum, + const char *file, unsigned int linenum, + const char *fmt, va_list ap) { + ++__error_message_count; + + fflush(stdout); + FLOCK(stderr); + + if (__error_print_progname) + __error_print_progname(); + else { + fprintf(stderr, "%s:", __progname_full); + if (!file) + fputc(' ', stderr); + } + + if (file) + fprintf(stderr, "%s:%u: ", file, linenum); + + vfprintf(stderr, fmt, ap); + if (errnum) + fprintf(stderr, ": %s", strerror(errnum)); + fputc('\n', stderr); + + fflush(stderr); + FUNLOCK(stderr); + + if (status) + exit(status); +} + +void __error(int status, int errnum, const char *fmt, ...) { + va_list ap; + va_start(ap, fmt); + errorv(status, errnum, NULL, 0, fmt, ap); + va_end(ap); +} + +void __error_at_line(int status, int errnum, + const char *file, unsigned int linenum, + const char *fmt, ...) { + if (error_one_per_line) { + if(saved_linenum == linenum && file != NULL && + saved_file != NULL && !strcmp(file, saved_file)) + return; + saved_linenum = linenum; + // Assuming that the lifetime of the passed in file name extends + // until the next call is rather questionable, but appears to be + // the expected semantics. + saved_file = file; + } + + va_list ap; + va_start(ap, fmt); + errorv(status, errnum, file, linenum, fmt, ap); + va_end(ap); +} + + +weak_alias(__error_print_progname, error_print_progname); +weak_alias(__error_message_count, error_message_count); +weak_alias(__error_one_per_line, error_one_per_line); + +weak_alias(__error, error); +weak_alias(__error_at_line, error_at_line); -- 2.22.0.657.g960e92d24f-goog