162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 262306a36Sopenharmony_ci/* Test that empty argvs are swapped out for a single empty string. */ 362306a36Sopenharmony_ci#include <stdio.h> 462306a36Sopenharmony_ci#include <unistd.h> 562306a36Sopenharmony_ci#include <sys/types.h> 662306a36Sopenharmony_ci#include <sys/wait.h> 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci#include "../kselftest.h" 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ci#define FORK(exec) \ 1162306a36Sopenharmony_cido { \ 1262306a36Sopenharmony_ci pid = fork(); \ 1362306a36Sopenharmony_ci if (pid == 0) { \ 1462306a36Sopenharmony_ci /* Child */ \ 1562306a36Sopenharmony_ci exec; /* Some kind of exec */ \ 1662306a36Sopenharmony_ci perror("# " #exec); \ 1762306a36Sopenharmony_ci return 1; \ 1862306a36Sopenharmony_ci } \ 1962306a36Sopenharmony_ci check_result(pid, #exec); \ 2062306a36Sopenharmony_ci} while (0) 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_civoid check_result(pid_t pid, const char *msg) 2362306a36Sopenharmony_ci{ 2462306a36Sopenharmony_ci int wstatus; 2562306a36Sopenharmony_ci 2662306a36Sopenharmony_ci if (pid == (pid_t)-1) { 2762306a36Sopenharmony_ci perror("# fork"); 2862306a36Sopenharmony_ci ksft_test_result_fail("fork failed: %s\n", msg); 2962306a36Sopenharmony_ci return; 3062306a36Sopenharmony_ci } 3162306a36Sopenharmony_ci if (waitpid(pid, &wstatus, 0) < 0) { 3262306a36Sopenharmony_ci perror("# waitpid"); 3362306a36Sopenharmony_ci ksft_test_result_fail("waitpid failed: %s\n", msg); 3462306a36Sopenharmony_ci return; 3562306a36Sopenharmony_ci } 3662306a36Sopenharmony_ci if (!WIFEXITED(wstatus)) { 3762306a36Sopenharmony_ci ksft_test_result_fail("child did not exit: %s\n", msg); 3862306a36Sopenharmony_ci return; 3962306a36Sopenharmony_ci } 4062306a36Sopenharmony_ci if (WEXITSTATUS(wstatus) != 0) { 4162306a36Sopenharmony_ci ksft_test_result_fail("non-zero exit: %s\n", msg); 4262306a36Sopenharmony_ci return; 4362306a36Sopenharmony_ci } 4462306a36Sopenharmony_ci ksft_test_result_pass("%s\n", msg); 4562306a36Sopenharmony_ci} 4662306a36Sopenharmony_ci 4762306a36Sopenharmony_ciint main(int argc, char *argv[], char *envp[]) 4862306a36Sopenharmony_ci{ 4962306a36Sopenharmony_ci pid_t pid; 5062306a36Sopenharmony_ci static char * const args[] = { NULL }; 5162306a36Sopenharmony_ci static char * const str[] = { "", NULL }; 5262306a36Sopenharmony_ci 5362306a36Sopenharmony_ci /* argc counting checks */ 5462306a36Sopenharmony_ci if (argc < 1) { 5562306a36Sopenharmony_ci fprintf(stderr, "# FAIL: saw argc == 0 (old kernel?)\n"); 5662306a36Sopenharmony_ci return 1; 5762306a36Sopenharmony_ci } 5862306a36Sopenharmony_ci if (argc != 1) { 5962306a36Sopenharmony_ci fprintf(stderr, "# FAIL: unknown argc (%d)\n", argc); 6062306a36Sopenharmony_ci return 1; 6162306a36Sopenharmony_ci } 6262306a36Sopenharmony_ci if (argv[0][0] == '\0') { 6362306a36Sopenharmony_ci /* Good, we found a NULL terminated string at argv[0]! */ 6462306a36Sopenharmony_ci return 0; 6562306a36Sopenharmony_ci } 6662306a36Sopenharmony_ci 6762306a36Sopenharmony_ci /* Test runner. */ 6862306a36Sopenharmony_ci ksft_print_header(); 6962306a36Sopenharmony_ci ksft_set_plan(5); 7062306a36Sopenharmony_ci 7162306a36Sopenharmony_ci FORK(execve(argv[0], str, NULL)); 7262306a36Sopenharmony_ci FORK(execve(argv[0], NULL, NULL)); 7362306a36Sopenharmony_ci FORK(execve(argv[0], NULL, envp)); 7462306a36Sopenharmony_ci FORK(execve(argv[0], args, NULL)); 7562306a36Sopenharmony_ci FORK(execve(argv[0], args, envp)); 7662306a36Sopenharmony_ci 7762306a36Sopenharmony_ci ksft_exit(ksft_cnt.ksft_pass == ksft_plan); 7862306a36Sopenharmony_ci} 79