The branch main has been updated by kib:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=01a679715f68d5e32efecafc1f158eecec3f781b

commit 01a679715f68d5e32efecafc1f158eecec3f781b
Author:     Konstantin Belousov <k...@freebsd.org>
AuthorDate: 2025-06-16 21:26:22 +0000
Commit:     Konstantin Belousov <k...@freebsd.org>
CommitDate: 2025-07-07 18:44:22 +0000

    err(3): print extended error if available
    
    Reviewed by:    asomers, brooks
    Sponsored by:   The FreeBSD Foundation
    Differential revision:  https://reviews.freebsd.org/D51141
---
 lib/libc/gen/err.c | 51 +++++++++++++++++++++++++++++++++++++++------------
 1 file changed, 39 insertions(+), 12 deletions(-)

diff --git a/lib/libc/gen/err.c b/lib/libc/gen/err.c
index 24ea242560b8..cdce20af5a91 100644
--- a/lib/libc/gen/err.c
+++ b/lib/libc/gen/err.c
@@ -30,9 +30,12 @@
  */
 
 #include "namespace.h"
+#include <sys/exterrvar.h>
 #include <err.h>
 #include <errno.h>
+#include <exterr.h>
 #include <stdarg.h>
+#include <stdbool.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -43,6 +46,11 @@
 static FILE *err_file; /* file to use for error output */
 static void (*err_exit)(int);
 
+static void verrci(bool doexterr, int eval, int code, const char *fmt,
+    va_list ap) __printf0like(4, 0) __dead2;
+static void vwarnci(bool doexterr, int code, const char *fmt, va_list ap)
+    __printf0like(3, 0);
+
 /*
  * This is declared to take a `void *' so that the caller is not required
  * to include <stdio.h> first.  However, it is really a `FILE *', and the
@@ -70,14 +78,14 @@ _err(int eval, const char *fmt, ...)
 {
        va_list ap;
        va_start(ap, fmt);
-       verrc(eval, errno, fmt, ap);
+       verrci(true, eval, errno, fmt, ap);
        va_end(ap);
 }
 
 void
 verr(int eval, const char *fmt, va_list ap)
 {
-       verrc(eval, errno, fmt, ap);
+       verrci(true, eval, errno, fmt, ap);
 }
 
 void
@@ -85,13 +93,24 @@ errc(int eval, int code, const char *fmt, ...)
 {
        va_list ap;
        va_start(ap, fmt);
-       verrc(eval, code, fmt, ap);
+       verrci(false, eval, code, fmt, ap);
        va_end(ap);
 }
 
 void
 verrc(int eval, int code, const char *fmt, va_list ap)
 {
+       verrci(false, eval, code, fmt, ap);
+}
+
+static void
+vexterr(bool doexterr, int code, const char *fmt, va_list ap)
+{
+       char exterr[UEXTERROR_MAXLEN];  /* libc knows the buffer size */
+       int extstatus;
+
+       if (doexterr)
+               extstatus = uexterr_gettext(exterr, sizeof(exterr));
        if (err_file == NULL)
                err_set_file(NULL);
        fprintf(err_file, "%s: ", _getprogname());
@@ -99,7 +118,16 @@ verrc(int eval, int code, const char *fmt, va_list ap)
                vfprintf(err_file, fmt, ap);
                fprintf(err_file, ": ");
        }
-       fprintf(err_file, "%s\n", strerror(code));
+       fprintf(err_file, "%s", strerror(code));
+       if (doexterr && extstatus == 0)
+               fprintf(err_file, " (extended error %s)", exterr);
+       fprintf(err_file, "\n");
+}
+
+static void
+verrci(bool doexterr, int eval, int code, const char *fmt, va_list ap)
+{
+       vexterr(doexterr, code, fmt, ap);
        if (err_exit)
                err_exit(eval);
        exit(eval);
@@ -156,18 +184,17 @@ warnc(int code, const char *fmt, ...)
 
 void
 vwarnc(int code, const char *fmt, va_list ap)
+{
+       vwarnci(false, code, fmt, ap);
+}
+
+static void
+vwarnci(bool doexterr, int code, const char *fmt, va_list ap)
 {
        int saved_errno;
 
        saved_errno = errno;
-       if (err_file == NULL)
-               err_set_file(NULL);
-       fprintf(err_file, "%s: ", _getprogname());
-       if (fmt != NULL) {
-               vfprintf(err_file, fmt, ap);
-               fprintf(err_file, ": ");
-       }
-       fprintf(err_file, "%s\n", strerror(code));
+       vexterr(doexterr, code, fmt, ap);
        errno = saved_errno;
 }
 

Reply via email to