1 /* Functional tests for spawn() syscall invoked indirectly via posix_spawn() 2 or system(). */ 3 4 #include <assert.h> 5 #include <fcntl.h> 6 #include <spawn.h> 7 #include <stdio.h> 8 #include <stdlib.h> 9 #include <strings.h> 10 #include <sys/wait.h> 11 12 13 #define EXE_NAME "../../../tests/true" 14 15 static volatile int sigchld_handled = 0; 16 static void sigchld_handler(int sig, siginfo_t *sip, void *ucontext) { 17 assert(sig == SIGCHLD); 18 sigchld_handled = 1; 19 } 20 21 int main(int argc, char *const argv[], char *const envp[]) { 22 int ret = system(EXE_NAME); 23 if (ret != 0) 24 perror("system"); 25 26 /* system() */ 27 ret = system(NULL); 28 if (ret == 0) 29 fprintf(stderr, "system() succeeded"); 30 31 /* posix_spawn(), no file actions, no attrs */ 32 char *const argv_exe[] = {"true", NULL}; 33 pid_t child; 34 ret = posix_spawn(&child, EXE_NAME, NULL, NULL, argv_exe, envp); 35 if (ret != 0) 36 perror("posix_spawn"); 37 waitpid(child, NULL, 0); 38 39 /* posix_spawn(), file actions, no attrs */ 40 posix_spawn_file_actions_t fa; 41 ret = posix_spawn_file_actions_init(&fa); 42 if (ret != 0) 43 perror("posix_spawn_file_actions_init"); 44 ret = posix_spawn_file_actions_addopen(&fa, 10, "/dev/null", O_RDONLY, 0); 45 if (ret != 0) 46 perror("posix_spawn_file_actions_addopen"); 47 ret = posix_spawn(&child, EXE_NAME, &fa, NULL, argv_exe, envp); 48 if (ret != 0) 49 perror("posix_spawn"); 50 waitpid(child, NULL, 0); 51 ret = posix_spawn_file_actions_destroy(&fa); 52 if (ret != 0) 53 perror("posix_spawn_file_actions_destroy"); 54 55 /* posix_spawn(), no file actions, attrs */ 56 posix_spawnattr_t spa; 57 ret = posix_spawnattr_init(&spa); 58 if (ret != 0) 59 perror("posix_spawnattr_init"); 60 ret = posix_spawnattr_setflags(&spa, POSIX_SPAWN_RESETIDS); 61 if (ret != 0) 62 perror("posix_spawnattr_setflags"); 63 ret = posix_spawn(&child, EXE_NAME, NULL, &spa, argv_exe, envp); 64 if (ret != 0) 65 perror("posix_spawn"); 66 waitpid(child, NULL, 0); 67 ret = posix_spawnattr_destroy(&spa); 68 if (ret != 0) 69 perror("posix_spawnattr_destroy"); 70 71 /* posix_spawn(), no file actions, no attrs, test SIGCHLD delivery */ 72 struct sigaction act; 73 bzero(&act, sizeof(act)); 74 act.sa_sigaction = sigchld_handler; 75 act.sa_flags = SA_SIGINFO; 76 ret = sigaction(SIGCHLD, &act, NULL); 77 if (ret != 0) 78 perror("sigaction"); 79 sigchld_handled = 0; 80 ret = posix_spawn(&child, EXE_NAME, NULL, NULL, argv_exe, envp); 81 if (ret != 0) 82 perror("posix_spawn"); 83 waitpid(child, NULL, 0); 84 if (sigchld_handled == 1) { 85 printf("PASS\n"); 86 } else { 87 printf("FAIL\n"); 88 } 89 90 /* posix_spawn(), no file actions, attrs, test *no* SIGCHLD delivery */ 91 ret = posix_spawnattr_init(&spa); 92 if (ret != 0) 93 perror("posix_spawnattr_init"); 94 ret = posix_spawnattr_setflags(&spa, POSIX_SPAWN_NOSIGCHLD_NP); 95 if (ret != 0) 96 perror("posix_spawnattr_setflags"); 97 sigchld_handled = 0; 98 ret = posix_spawn(&child, EXE_NAME, NULL, &spa, argv_exe, envp); 99 if (ret != 0) 100 perror("posix_spawn"); 101 waitpid(child, NULL, 0); 102 if (sigchld_handled == 0) { 103 printf("PASS\n"); 104 } else { 105 printf("FAIL\n"); 106 } 107 ret = posix_spawnattr_destroy(&spa); 108 if (ret != 0) 109 perror("posix_spawnattr_destroy"); 110 111 return 0; 112 } 113