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;
sigchld_handler(int sig,siginfo_t * sip,void * ucontext)16 static void sigchld_handler(int sig, siginfo_t *sip, void *ucontext) {
17 assert(sig == SIGCHLD);
18 sigchld_handled = 1;
19 }
20
main(int argc,char * const argv[],char * const envp[])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