summaryrefslogtreecommitdiff
path: root/tools/testing
diff options
context:
space:
mode:
authorThomas Weißschuh <linux@weissschuh.net>2026-03-18 18:50:16 +0300
committerThomas Weißschuh <linux@weissschuh.net>2026-03-22 12:40:30 +0300
commitb74be922745989573eedee2a91d987711ef968bd (patch)
tree1df7c8d21df1bf7b680ee6d3637c034128cb970d /tools/testing
parent5662ec000d97d7a84ad4e3f34768ef08c869d0e3 (diff)
downloadlinux-b74be922745989573eedee2a91d987711ef968bd.tar.xz
tools/nolibc: add support for program_invocation_{,short_}name
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ßschuh <linux@weissschuh.net> Acked-by: Willy Tarreau <w@1wt.eu> Link: https://patch.msgid.link/20260318-nolibc-err-h-v4-1-08247a694bd9@weissschuh.net
Diffstat (limited to 'tools/testing')
-rw-r--r--tools/testing/selftests/nolibc/nolibc-test.c34
1 files changed, 34 insertions, 0 deletions
diff --git a/tools/testing/selftests/nolibc/nolibc-test.c b/tools/testing/selftests/nolibc/nolibc-test.c
index 0ca695acbc44..1efd10152e83 100644
--- a/tools/testing/selftests/nolibc/nolibc-test.c
+++ b/tools/testing/selftests/nolibc/nolibc-test.c
@@ -42,6 +42,7 @@
#include <unistd.h>
#include <limits.h>
#include <ctype.h>
+#include <stdbool.h>
#pragma GCC diagnostic ignored "-Wmissing-prototypes"
@@ -710,6 +711,37 @@ static void constructor2(int argc, char **argv, char **envp)
constructor_test_value |= 1 << 1;
}
+int test_program_invocation_name(void)
+{
+ char buf[100];
+ char *dirsep;
+ ssize_t r;
+ int fd;
+
+ fd = open("/proc/self/cmdline", O_RDONLY);
+ if (fd == -1)
+ return 1;
+
+ r = read(fd, buf, sizeof(buf));
+ close(fd);
+ if (r < 1 || r == sizeof(buf))
+ return 1;
+
+ buf[r - 1] = '\0';
+
+ if (strcmp(program_invocation_name, buf) != 0)
+ return 1;
+
+ dirsep = strrchr(buf, '/');
+ if (!dirsep || dirsep[1] == '\0')
+ return 1;
+
+ if (strcmp(program_invocation_short_name, dirsep + 1) != 0)
+ return 1;
+
+ return 0;
+}
+
int run_startup(int min, int max)
{
int test;
@@ -724,6 +756,7 @@ int run_startup(int min, int max)
#ifdef NOLIBC
test_auxv = _auxv;
#endif
+ bool proc = access("/proc", R_OK) == 0;
for (test = min; test >= 0 && test <= max; test++) {
int llen = 0; /* line length */
@@ -749,6 +782,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_name()); break;
case __LINE__:
return ret; /* must be last */
/* note: do not set any defaults so as to permit holes above */