From nobody Tue Apr 7 02:37:33 2026 Received: from todd.t-8ch.de (todd.t-8ch.de [159.69.126.157]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 75989357A4A; Mon, 16 Mar 2026 21:58:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=159.69.126.157 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773698339; cv=none; b=oAMXlnktQuB5M9aQOYP2airtRoJHsakQ4SEMMnq9cgEEdg0f6SbSJWWJJiys+jypXansHJqDaEHpBF7OEA0fuAoEe7bK2tNauZJF0wsqAG/CptfKOj+I+i8ajMugHgaUFTn3RPlipuLlPf5ojyqqbrphVDCWU9ZueDSMyVSGHco= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773698339; c=relaxed/simple; bh=UXwH0L1n9dRh7aiNabmuyTyMypVw1624YCLDekb4I1E=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=sxXuyodA6bsWqJiLJztr/+YFEfd/dSyCWuiDnnd3vUX6087INK3BhMmPVQRWsYFMSFsPRtpFnhHcEURzM00cmqx9q0H6B7NsK2f28QqN06LgL9Pm4d1VCoNoWlQdppCsj6NXiOAcl39Dawf2xUbxZVwGD8xpzbaHW/MVF+PkaJU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=weissschuh.net; spf=pass smtp.mailfrom=weissschuh.net; dkim=pass (1024-bit key) header.d=weissschuh.net header.i=@weissschuh.net header.b=La9cGOm0; arc=none smtp.client-ip=159.69.126.157 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=weissschuh.net Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=weissschuh.net Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=weissschuh.net header.i=@weissschuh.net header.b="La9cGOm0" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=weissschuh.net; s=mail; t=1773698335; bh=UXwH0L1n9dRh7aiNabmuyTyMypVw1624YCLDekb4I1E=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=La9cGOm0VPpwo4hmBZfJE6o6l2Iumu31X5qf7PCARzMvYk3hzkywwqTw93bU5z5Eu fSmoISF6hzTPWz2wX0ootlNq7xK7kgPWgVf9WD6TlW3U9jNHmdUU8VbdPldfslVrQZ fXDOdPce31z2lCK/5rCAQQQ2wMLuJwEER5kxF12A= From: =?utf-8?q?Thomas_Wei=C3=9Fschuh?= Date: Mon, 16 Mar 2026 22:58:50 +0100 Subject: [PATCH v3 1/2] tools/nolibc: add support for program_invocation_{,short_}name Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260316-nolibc-err-h-v3-1-6ef80c051ab7@weissschuh.net> References: <20260316-nolibc-err-h-v3-0-6ef80c051ab7@weissschuh.net> In-Reply-To: <20260316-nolibc-err-h-v3-0-6ef80c051ab7@weissschuh.net> To: Willy Tarreau , Shuah Khan Cc: linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, =?utf-8?q?Thomas_Wei=C3=9Fschuh?= X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1773698335; l=4906; i=linux@weissschuh.net; s=20221212; h=from:subject:message-id; bh=UXwH0L1n9dRh7aiNabmuyTyMypVw1624YCLDekb4I1E=; b=GU8Zck35kK3Tmb6G81Wt+AhlVKSMHjQv8c0N1wusD4cTwiQQBMsfq1HLt5WjTbDxURXdZGwtj 61Tgsmjw2ONB+4cZPl1jVDnKv8159Bqw10T4HEgswyCGc+Gidy5sxZA X-Developer-Key: i=linux@weissschuh.net; a=ed25519; pk=KcycQgFPX2wGR5azS7RhpBqedglOZVgRPfdFSPB1LNw= Add support for the GNU extensions 'program_invocation_name' and 'program_invocation_short_name'. These are useful to print error messages, which by convention include the program name. As these are global variables which take up memory even if not used, similar to 'errno', gate them behind NOLIBC_IGNORE_ERRNO. Signed-off-by: Thomas Wei=C3=9Fschuh --- tools/include/nolibc/crt.h | 26 ++++++++++++++++++++++ tools/include/nolibc/errno.h | 4 ++++ tools/testing/selftests/nolibc/nolibc-test.c | 33 ++++++++++++++++++++++++= ++++ 3 files changed, 63 insertions(+) diff --git a/tools/include/nolibc/crt.h b/tools/include/nolibc/crt.h index d9262998dae9..5bb492555f13 100644 --- a/tools/include/nolibc/crt.h +++ b/tools/include/nolibc/crt.h @@ -17,6 +17,7 @@ const unsigned long *_auxv __attribute__((weak)); void _start(void); static void __stack_chk_init(void); static void exit(int); +static char *strrchr(const char *s, int c); =20 extern void (*const __preinit_array_start[])(int, char **, char**) __attri= bute__((weak)); extern void (*const __preinit_array_end[])(int, char **, char**) __attribu= te__((weak)); @@ -27,6 +28,24 @@ extern void (*const __init_array_end[])(int, char **, ch= ar**) __attribute__((wea extern void (*const __fini_array_start[])(void) __attribute__((weak)); extern void (*const __fini_array_end[])(void) __attribute__((weak)); =20 +#ifndef NOLIBC_IGNORE_ERRNO +extern char *program_invocation_name __attribute__((weak)); +extern char *program_invocation_short_name __attribute__((weak)); + +static __inline__ +char *__nolibc_program_invocation_short_name(char *long_name) +{ + + char *short_name; + + short_name =3D strrchr(long_name, '/'); + if (!short_name || !short_name[0]) + return long_name; + + return short_name + 1; +} +#endif /* NOLIBC_IGNORE_ERRNO */ + void _start_c(long *sp); __attribute__((weak,used)) #if __nolibc_has_feature(undefined_behavior_sanitizer) @@ -76,6 +95,13 @@ void _start_c(long *sp) ; _auxv =3D auxv; =20 +#ifndef NOLIBC_IGNORE_ERRNO + if (argc > 0 && argv[0]) { + program_invocation_name =3D argv[0]; + program_invocation_short_name =3D __nolibc_program_invocation_short_name= (argv[0]); + } +#endif /* NOLIBC_IGNORE_ERRNO */ + for (ctor_func =3D __preinit_array_start; ctor_func < __preinit_array_end= ; ctor_func++) (*ctor_func)(argc, argv, envp); for (ctor_func =3D __init_array_start; ctor_func < __init_array_end; ctor= _func++) diff --git a/tools/include/nolibc/errno.h b/tools/include/nolibc/errno.h index 08a33c40ec0c..bab83692ea1c 100644 --- a/tools/include/nolibc/errno.h +++ b/tools/include/nolibc/errno.h @@ -15,8 +15,12 @@ #ifndef NOLIBC_IGNORE_ERRNO #define SET_ERRNO(v) do { errno =3D (v); } while (0) int errno __attribute__((weak)); +char *program_invocation_name __attribute__((weak)) =3D ""; +char *program_invocation_short_name __attribute__((weak)) =3D ""; #else #define SET_ERRNO(v) do { } while (0) +#define program_invocation_name "" +#define program_invocation_short_name "" #endif =20 =20 diff --git a/tools/testing/selftests/nolibc/nolibc-test.c b/tools/testing/s= elftests/nolibc/nolibc-test.c index 180611aabbfb..07af23833879 100644 --- a/tools/testing/selftests/nolibc/nolibc-test.c +++ b/tools/testing/selftests/nolibc/nolibc-test.c @@ -702,6 +702,37 @@ static void constructor2(int argc, char **argv, char *= *envp) constructor_test_value |=3D 1 << 1; } =20 +int test_program_invocation_name(void) +{ + char buf[100]; + char *dirsep; + ssize_t r; + int fd; + + fd =3D open("/proc/self/cmdline", O_RDONLY); + if (fd =3D=3D -1) + return 1; + + r =3D read(fd, buf, sizeof(buf)); + close(fd); + if (r < 1 || r =3D=3D sizeof(buf)) + return 1; + + buf[r - 1] =3D '\0'; + + if (strcmp(program_invocation_name, buf) !=3D 0) + return 1; + + dirsep =3D strrchr(buf, '/'); + if (!dirsep || dirsep[1] =3D=3D '\0') + return 1; + + if (strcmp(program_invocation_short_name, dirsep + 1) !=3D 0) + return 1; + + return 0; +} + int run_startup(int min, int max) { int test; @@ -716,6 +747,7 @@ int run_startup(int min, int max) #ifdef NOLIBC test_auxv =3D _auxv; #endif + bool proc =3D access("/proc", R_OK) =3D=3D 0; =20 for (test =3D min; test >=3D 0 && test <=3D max; test++) { int llen =3D 0; /* line length */ @@ -741,6 +773,7 @@ int run_startup(int min, int max) CASE_TEST(constructor); EXPECT_EQ(is_nolibc, constructor_test_value= , 0x3); break; CASE_TEST(linkage_errno); EXPECT_PTREQ(1, linkage_test_errno_addr(), = &errno); break; CASE_TEST(linkage_constr); EXPECT_EQ(1, linkage_test_constructor_test_= value, 0x3); break; + CASE_TEST(prog_name); EXPECT_ZR(proc, test_program_invocation_nam= e()); break; case __LINE__: return ret; /* must be last */ /* note: do not set any defaults so as to permit holes above */ --=20 2.53.0 From nobody Tue Apr 7 02:37:33 2026 Received: from todd.t-8ch.de (todd.t-8ch.de [159.69.126.157]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3FAAC36A038; Mon, 16 Mar 2026 21:58:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=159.69.126.157 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773698339; cv=none; b=V5BLNpdrtpv1nwVq2SFGeW+qJbSDV0Zq33FlDhbR0vigHrkNVbYw0WUNo1XBCTsCXozUBcjYO9HZCss9mofTE6NXt6hjYH4TPsgvq6WBFP36W48ezAX2PAYwUXoW8SH2CMziaZJIvjm4Zl6xXSmKR8J5Q7RSE3UAQUZCpDI3OpU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773698339; c=relaxed/simple; bh=ppeFS/esmOXFVznMHGq33Ol4W76goRqIc1twAuAacu4=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=vEqMc0sFOcSa705inZrLtnkSgCP5Cne16eUZYEqg/QK1VT7O2fKQWwPHI45cPXT6LwZuL0B5tCwFrNgwmOAeCpIfTdiIFgzGck7l0+Yt49gwe8enGaP6tjRnsUAAJGLTzOupzq2il/URHcIvTJ19gvTxOhzVIOQNkQEN11qsDEg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=weissschuh.net; spf=pass smtp.mailfrom=weissschuh.net; dkim=pass (1024-bit key) header.d=weissschuh.net header.i=@weissschuh.net header.b=oLfb1eR1; arc=none smtp.client-ip=159.69.126.157 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=weissschuh.net Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=weissschuh.net Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=weissschuh.net header.i=@weissschuh.net header.b="oLfb1eR1" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=weissschuh.net; s=mail; t=1773698335; bh=ppeFS/esmOXFVznMHGq33Ol4W76goRqIc1twAuAacu4=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=oLfb1eR1ghjjMn3hxicgEyNYeZdAdfM6LuCyh4WlmIsVfLnz9lAnPgs3cNzvbGacf x5EXp/EZev38wGQlyF/lQhlkPmSe5HJWwU01ZuooJxDNlKO0Zx5ElJ9PQxTmV5l6DK l5GG816w2RH7XxM7zBIMHqGVTEIj3bc6A/66y9qk= From: =?utf-8?q?Thomas_Wei=C3=9Fschuh?= Date: Mon, 16 Mar 2026 22:58:51 +0100 Subject: [PATCH v3 2/2] tools/nolibc: add err.h Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260316-nolibc-err-h-v3-2-6ef80c051ab7@weissschuh.net> References: <20260316-nolibc-err-h-v3-0-6ef80c051ab7@weissschuh.net> In-Reply-To: <20260316-nolibc-err-h-v3-0-6ef80c051ab7@weissschuh.net> To: Willy Tarreau , Shuah Khan Cc: linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, =?utf-8?q?Thomas_Wei=C3=9Fschuh?= X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1773698335; l=2997; i=linux@weissschuh.net; s=20221212; h=from:subject:message-id; bh=ppeFS/esmOXFVznMHGq33Ol4W76goRqIc1twAuAacu4=; b=ymz0OoloIYzOXrkWwl6Kdw+utZju0A2wBojTFHjZi+Q2lgkRVmYzRULFyyqjGcwHsf4c2rQEI PUPG8qVf2gwC7UCM2gI58wAairC8DlOleiWdmaXE4BdrwkySEaQGALg X-Developer-Key: i=linux@weissschuh.net; a=ed25519; pk=KcycQgFPX2wGR5azS7RhpBqedglOZVgRPfdFSPB1LNw= Add a few convenient helpers to print error and warning messages. Signed-off-by: Thomas Wei=C3=9Fschuh --- tools/include/nolibc/Makefile | 1 + tools/include/nolibc/err.h | 87 +++++++++++++++++++++++++++++++++++++++= ++++ tools/include/nolibc/nolibc.h | 1 + 3 files changed, 89 insertions(+) diff --git a/tools/include/nolibc/Makefile b/tools/include/nolibc/Makefile index 1958dda98895..5d242312943f 100644 --- a/tools/include/nolibc/Makefile +++ b/tools/include/nolibc/Makefile @@ -30,6 +30,7 @@ all_files :=3D \ ctype.h \ dirent.h \ elf.h \ + err.h \ errno.h \ fcntl.h \ getopt.h \ diff --git a/tools/include/nolibc/err.h b/tools/include/nolibc/err.h new file mode 100644 index 000000000000..e22ae87a7289 --- /dev/null +++ b/tools/include/nolibc/err.h @@ -0,0 +1,87 @@ +/* SPDX-License-Identifier: LGPL-2.1 OR MIT */ +/* + * formatted error message for NOLIBC + * Copyright (C) 2026 Thomas Wei=C3=9Fschuh + */ + +/* make sure to include all global symbols */ +#include "nolibc.h" + +#ifndef _NOLIBC_ERR_H +#define _NOLIBC_ERR_H + +#include "errno.h" +#include "stdarg.h" +#include "sys.h" + +static __attribute__((unused)) +void vwarn(const char *fmt, va_list args) +{ + fprintf(stderr, "%s: ", program_invocation_short_name); + vfprintf(stderr, fmt, args); + fprintf(stderr, ": %m\n"); +} + +static __attribute__((unused)) +void vwarnx(const char *fmt, va_list args) +{ + fprintf(stderr, "%s: ", program_invocation_short_name); + vfprintf(stderr, fmt, args); + fprintf(stderr, "\n"); +} + +static __attribute__((unused)) +void warn(const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + vwarn(fmt, args); + va_end(args); +} + +static __attribute__((unused)) +void warnx(const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + vwarnx(fmt, args); + va_end(args); +} + +static __attribute__((noreturn, unused)) +void verr(int eval, const char *fmt, va_list args) +{ + vwarn(fmt, args); + exit(eval); +} + +static __attribute__((noreturn, unused)) +void verrx(int eval, const char *fmt, va_list args) +{ + warnx(fmt, args); + exit(eval); +} + +static __attribute__((noreturn, unused)) +void err(int eval, const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + verr(eval, fmt, args); + va_end(args); +} + +static __attribute__((noreturn, unused)) +void errx(int eval, const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + verrx(eval, fmt, args); + va_end(args); +} + +#endif /* _NOLIBC_ERR_H */ diff --git a/tools/include/nolibc/nolibc.h b/tools/include/nolibc/nolibc.h index d1d08b7f8599..fe8195483b6d 100644 --- a/tools/include/nolibc/nolibc.h +++ b/tools/include/nolibc/nolibc.h @@ -130,6 +130,7 @@ #include "getopt.h" #include "poll.h" #include "math.h" +#include "err.h" =20 /* Used by programs to avoid std includes */ #define NOLIBC --=20 2.53.0