Index: b/usr/src/head/Makefile =================================================================== --- a/usr/src/head/Makefile +++ b/usr/src/head/Makefile @@ -67,6 +67,7 @@ HDRS= $($(MACH)_HDRS) $(ATTRDB_HDRS) elf.h \ err.h \ errno.h \ + error.h \ euc.h \ exacct.h \ exacct_impl.h \ Index: b/usr/src/head/error.h =================================================================== --- /dev/null +++ b/usr/src/head/error.h @@ -0,0 +1,44 @@ +/* +Copyright: 2013, Igor Pashev +License: WTFPL-2 + DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE + Version 2, December 2004 + + Copyright (C) 2004 Sam Hocevar + + Everyone is permitted to copy and distribute verbatim or modified + copies of this license document, and changing it is allowed as long + as the name is changed. + + DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. You just DO WHAT THE FUCK YOU WANT TO. + + */ + + +#ifndef _ERROR_H +#define _ERROR_H + +#ifdef __cplusplus +extern "C" { +#endif + +void error(int status, int errnum, const char *format, ...); + +void error_at_line(int status, int errnum, const char *filename, + unsigned int linenum, const char *format, ...); + +extern unsigned int error_message_count; + +extern int error_one_per_line; + +extern void (* error_print_progname) (void); + +#ifdef __cplusplus +} +#endif + +#endif /* _ERROR_H */ + Index: b/usr/src/lib/libc/amd64/Makefile =================================================================== --- a/usr/src/lib/libc/amd64/Makefile +++ b/usr/src/lib/libc/amd64/Makefile @@ -116,6 +116,7 @@ GENOBJS= \ cuexit.o \ ecvt.o \ errlst.o \ + error.o \ amd64_data.o \ ldivide.o \ lock.o \ Index: b/usr/src/lib/libc/i386/Makefile.com =================================================================== --- a/usr/src/lib/libc/i386/Makefile.com +++ b/usr/src/lib/libc/i386/Makefile.com @@ -123,6 +123,7 @@ GENOBJS= \ cuexit.o \ ecvt.o \ errlst.o \ + error.o \ i386_data.o \ ladd.o \ ldivide.o \ Index: b/usr/src/lib/libc/port/gen/error.c =================================================================== --- /dev/null +++ b/usr/src/lib/libc/port/gen/error.c @@ -0,0 +1,94 @@ +/* +Copyright: 2013, Igor Pashev +License: WTFPL-2 + DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE + Version 2, December 2004 + + Copyright (C) 2004 Sam Hocevar + + Everyone is permitted to copy and distribute verbatim or modified + copies of this license document, and changing it is allowed as long + as the name is changed. + + DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. You just DO WHAT THE FUCK YOU WANT TO. + + */ + +#include "stdarg.h" +#include "stdio.h" +#include "string.h" +#include "stdlib.h" + +#define _GNU_SOURCE +#include "errno.h" + +#include "error.h" + +unsigned int error_message_count = 0; +int error_one_per_line = 0; +void (* error_print_progname) (void) = NULL; + +static +void __real_error_at_line(int status, int errnum, const char *filename, + unsigned int linenum, const char *format, va_list argp) +{ + +/* TODO: + * If the global variable error_one_per_line is set nonzero, a sequence + * of error_at_line() calls with the same value of filename and linenum will + * result in only one message (the first) being output. + */ + + error_message_count++; + + fflush(stdout); + + if (NULL != error_print_progname) { + (*error_print_progname)(); + } else { + fputs(program_invocation_name, stderr); + } + + if (NULL != filename) { + fprintf(stderr, ":%s", filename); + if (0 != linenum) { + fprintf(stderr, ":%u", linenum); + } + } + + fputs(": ", stderr); + vfprintf(stderr, format, argp); + + if (0 != errnum) { + fprintf(stderr, ": %s", strerror(errnum)); + } + + fputs("\n", stderr); + + if (0 != status) { + exit(status); + } +} + +void error_at_line(int status, int errnum, const char *filename, + unsigned int linenum, const char *format, ...) +{ + va_list ap; + + va_start(ap, format); + __real_error_at_line(status, errnum, filename, linenum, format, ap); + va_end(ap); +} + +void error(int status, int errnum, const char *format, ...) +{ + va_list ap; + + va_start(ap, format); + __real_error_at_line(status, errnum, NULL, 0, format, ap); + va_end(ap); +} + Index: b/usr/src/lib/libc/port/mapfile-vers =================================================================== --- a/usr/src/lib/libc/port/mapfile-vers +++ b/usr/src/lib/libc/port/mapfile-vers @@ -269,7 +269,14 @@ $endif SYMBOL_VERSION DYSON_1 { global: + error; + error_at_line; + error_message_count; + error_one_per_line; + error_print_progname; mempcpy; + program_invocation_name; + program_invocation_short_name; } ILLUMOS_0.3; SYMBOL_VERSION ILLUMOS_0.3 { # Illumos additions Index: b/usr/src/lib/libc/port/gen/err.c =================================================================== --- a/usr/src/lib/libc/port/gen/err.c +++ b/usr/src/lib/libc/port/gen/err.c @@ -40,6 +40,8 @@ /* Function exit/warning functions and global variables. */ const char *__progname; /* GNU/Linux/BSD compatibility */ +char *program_invocation_name; +char *program_invocation_short_name; #define PROGNAMESIZE 128 /* buffer size for __progname */ @@ -64,6 +66,9 @@ setprogname(const char *argv0) udp->progname = lmalloc(PROGNAMESIZE); (void) strlcpy(udp->progname, progname, PROGNAMESIZE); __progname = udp->progname; + + program_invocation_short_name = (char *) __progname; + program_invocation_name = (char *) argv0; } /* called only from libc_init() */ Index: b/usr/src/head/errno.h =================================================================== --- a/usr/src/head/errno.h +++ b/usr/src/head/errno.h @@ -44,6 +44,11 @@ extern "C" { #endif +#if defined (_GNU_SOURCE) || defined (__EXTENSIONS__) +extern char *program_invocation_name; +extern char *program_invocation_short_name; +#endif + #if defined(_LP64) /* * The symbols _sys_errlist and _sys_nerr are not visible in the