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 } 79