git: 42210fe8dcd4 - main - exterror: Add EXTERROR_VERBOSE env variable to control verbosity
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 29 Dec 2025 01:16:34 UTC
The branch main has been updated by kib:
URL: https://cgit.FreeBSD.org/src/commit/?id=42210fe8dcd4684a45e0e4db1b8194e291dc8fda
commit 42210fe8dcd4684a45e0e4db1b8194e291dc8fda
Author: Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2025-12-28 00:23:27 +0000
Commit: Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2025-12-29 01:16:25 +0000
exterror: Add EXTERROR_VERBOSE env variable to control verbosity
If the variable is set and the process is not suid, __uexterr_format(),
used by err(3), prints errno/category/source line/pX always, not only
when there is no kernel message provided.
Requested by: mckusick
Reviewed by: emaste, mckusick
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Differential revision: https://reviews.freebsd.org/D54380
---
lib/libc/gen/uexterr_format.c | 53 +++++++++++++++++++++++++++++++++++++++----
1 file changed, 48 insertions(+), 5 deletions(-)
diff --git a/lib/libc/gen/uexterr_format.c b/lib/libc/gen/uexterr_format.c
index 68cd2abfe312..3321fd80616d 100644
--- a/lib/libc/gen/uexterr_format.c
+++ b/lib/libc/gen/uexterr_format.c
@@ -11,26 +11,69 @@
#include <sys/types.h>
#include <sys/exterrvar.h>
#include <exterr.h>
+#include <stdbool.h>
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
+#include <unistd.h>
+
+static const char exterror_verbose_name[] = "EXTERROR_VERBOSE";
+enum exterr_verbose_state {
+ EXTERR_VERBOSE_UNKNOWN = 100,
+ EXTERR_VERBOSE_DEFAULT,
+ EXTERR_VERBOSE_ALLOW,
+};
+static enum exterr_verbose_state exterror_verbose = EXTERR_VERBOSE_UNKNOWN;
+
+static void
+exterr_verbose_init(void)
+{
+ /*
+ * No need to care about thread-safety, the result is
+ * idempotent.
+ */
+ if (exterror_verbose != EXTERR_VERBOSE_UNKNOWN)
+ return;
+ if (issetugid()) {
+ exterror_verbose = EXTERR_VERBOSE_DEFAULT;
+ } else if (getenv(exterror_verbose_name) != NULL) {
+ exterror_verbose = EXTERR_VERBOSE_ALLOW;
+ } else {
+ exterror_verbose = EXTERR_VERBOSE_DEFAULT;
+ }
+}
int
__uexterr_format(const struct uexterror *ue, char *buf, size_t bufsz)
{
+ bool has_msg;
+
if (bufsz > UEXTERROR_MAXLEN)
bufsz = UEXTERROR_MAXLEN;
if (ue->error == 0) {
strlcpy(buf, "", bufsz);
return (0);
}
- if (ue->msg[0] == '\0') {
- snprintf(buf, bufsz,
+ exterr_verbose_init();
+ has_msg = ue->msg[0] != '\0';
+
+ if (has_msg) {
+ snprintf(buf, bufsz, ue->msg, (uintmax_t)ue->p1,
+ (uintmax_t)ue->p2);
+ } else {
+ strlcpy(buf, "", bufsz);
+ }
+
+ if (exterror_verbose == EXTERR_VERBOSE_ALLOW || !has_msg) {
+ char lbuf[128];
+
+ snprintf(lbuf, sizeof(lbuf),
"errno %d category %u (src line %u) p1 %#jx p2 %#jx",
ue->error, ue->cat, ue->src_line,
(uintmax_t)ue->p1, (uintmax_t)ue->p2);
- } else {
- snprintf(buf, bufsz, ue->msg, (uintmax_t)ue->p1,
- (uintmax_t)ue->p2);
+ if (has_msg)
+ strlcat(buf, " ", bufsz);
+ strlcat(buf, lbuf, bufsz);
}
return (0);
}