nolibc-test does not call any of the err.h functions, so nothing noticed that verrx(), and errx() through it, printed their messages with the wrong arguments, or crashed.
Add a test that calls errx() in a child with stderr redirected to a pipe, and checks the exit status and the message. Assisted-by: LLM Signed-off-by: Danish Khateeb <[email protected]> --- tools/testing/selftests/nolibc/nolibc-test.c | 47 ++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/tools/testing/selftests/nolibc/nolibc-test.c b/tools/testing/selftests/nolibc/nolibc-test.c index 37c11a7fce23..1447c2e39af5 100644 --- a/tools/testing/selftests/nolibc/nolibc-test.c +++ b/tools/testing/selftests/nolibc/nolibc-test.c @@ -32,6 +32,7 @@ #include <sys/utsname.h> #include <sys/wait.h> #include <dirent.h> +#include <err.h> #include <errno.h> #include <fcntl.h> #include <poll.h> @@ -2223,6 +2224,51 @@ int test_asprintf(void) return 0; } +int test_errx(void) +{ + char buf[100], expected[100]; + int pipefd[2], status; + ssize_t len; + pid_t pid; + + if (pipe(pipefd) == -1) + return 1; + + /* flush the printf buffer to avoid child flush it */ + fflush(stdout); + fflush(stderr); + + pid = fork(); + if (pid == -1) { + close(pipefd[0]); + close(pipefd[1]); + return 2; + } + + if (pid == 0) { + dup2(pipefd[1], STDERR_FILENO); + errx(42, "%d %s", 1234, "foo"); + } + + close(pipefd[1]); + pid = waitpid(pid, &status, 0); + len = read(pipefd[0], buf, sizeof(buf) - 1); + close(pipefd[0]); + + if (pid == -1 || !WIFEXITED(status) || WEXITSTATUS(status) != 42) + return 3; + + if (len == -1) + return 4; + buf[len] = 0; + + snprintf(expected, sizeof(expected), "%s: 1234 foo\n", program_invocation_short_name); + if (strcmp(buf, expected) != 0) + return 5; + + return 0; +} + static int run_printf(int min, int max) { int test; @@ -2287,6 +2333,7 @@ static int run_printf(int min, int max) CASE_TEST(scanf); EXPECT_ZR(1, test_scanf()); break; CASE_TEST(printf_error); EXPECT_ZR(1, test_printf_error()); break; CASE_TEST(asprintf); EXPECT_ZR(1, test_asprintf()); break; + CASE_TEST(errx); EXPECT_ZR(1, test_errx()); break; case __LINE__: return ret; /* must be last */ /* note: do not set any defaults so as to permit holes above */ -- 2.55.0

