|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
| 2 | +/* Test that empty argvs are swapped out for a single empty string. */ |
| 3 | +#include <stdio.h> |
| 4 | +#include <unistd.h> |
| 5 | +#include <sys/types.h> |
| 6 | +#include <sys/wait.h> |
| 7 | + |
| 8 | +#include "../kselftest.h" |
| 9 | + |
| 10 | +#define FORK(exec) \ |
| 11 | +do { \ |
| 12 | + pid = fork(); \ |
| 13 | + if (pid == 0) { \ |
| 14 | + /* Child */ \ |
| 15 | + exec; /* Some kind of exec */ \ |
| 16 | + perror("# " #exec); \ |
| 17 | + return 1; \ |
| 18 | + } \ |
| 19 | + check_result(pid, #exec); \ |
| 20 | +} while (0) |
| 21 | + |
| 22 | +void check_result(pid_t pid, const char *msg) |
| 23 | +{ |
| 24 | + int wstatus; |
| 25 | + |
| 26 | + if (pid == (pid_t)-1) { |
| 27 | + perror("# fork"); |
| 28 | + ksft_test_result_fail("fork failed: %s\n", msg); |
| 29 | + return; |
| 30 | + } |
| 31 | + if (waitpid(pid, &wstatus, 0) < 0) { |
| 32 | + perror("# waitpid"); |
| 33 | + ksft_test_result_fail("waitpid failed: %s\n", msg); |
| 34 | + return; |
| 35 | + } |
| 36 | + if (!WIFEXITED(wstatus)) { |
| 37 | + ksft_test_result_fail("child did not exit: %s\n", msg); |
| 38 | + return; |
| 39 | + } |
| 40 | + if (WEXITSTATUS(wstatus) != 0) { |
| 41 | + ksft_test_result_fail("non-zero exit: %s\n", msg); |
| 42 | + return; |
| 43 | + } |
| 44 | + ksft_test_result_pass("%s\n", msg); |
| 45 | +} |
| 46 | + |
| 47 | +int main(int argc, char *argv[], char *envp[]) |
| 48 | +{ |
| 49 | + pid_t pid; |
| 50 | + static char * const args[] = { NULL }; |
| 51 | + static char * const str[] = { "", NULL }; |
| 52 | + |
| 53 | + /* argc counting checks */ |
| 54 | + if (argc < 1) { |
| 55 | + fprintf(stderr, "# FAIL: saw argc == 0 (old kernel?)\n"); |
| 56 | + return 1; |
| 57 | + } |
| 58 | + if (argc != 1) { |
| 59 | + fprintf(stderr, "# FAIL: unknown argc (%d)\n", argc); |
| 60 | + return 1; |
| 61 | + } |
| 62 | + if (argv[0][0] == '\0') { |
| 63 | + /* Good, we found a NULL terminated string at argv[0]! */ |
| 64 | + return 0; |
| 65 | + } |
| 66 | + |
| 67 | + /* Test runner. */ |
| 68 | + ksft_print_header(); |
| 69 | + ksft_set_plan(5); |
| 70 | + |
| 71 | + FORK(execve(argv[0], str, NULL)); |
| 72 | + FORK(execve(argv[0], NULL, NULL)); |
| 73 | + FORK(execve(argv[0], NULL, envp)); |
| 74 | + FORK(execve(argv[0], args, NULL)); |
| 75 | + FORK(execve(argv[0], args, envp)); |
| 76 | + |
| 77 | + ksft_exit(ksft_cnt.ksft_pass == ksft_plan); |
| 78 | +} |
0 commit comments