2 * Based off tests/lib/libc/gen/posix_spawn/t_spawn.c
5 /* $NetBSD: t_spawn.c,v 1.1 2012/02/13 21:03:08 martin Exp $ */
8 * Copyright (c) 2012 The NetBSD Foundation, Inc.
11 * This code is derived from software contributed to The NetBSD Foundation
12 * by Charles Zhang <charles@NetBSD.org> and
13 * Martin Husemann <martin@NetBSD.org>.
15 * Redistribution and use in source and binary forms, with or without
16 * modification, are permitted provided that the following conditions
18 * 1. Redistributions of source code must retain the above copyright
19 * notice, this list of conditions and the following disclaimer.
20 * 2. Redistributions in binary form must reproduce the above copyright
21 * notice, this list of conditions and the following disclaimer in the
22 * documentation and/or other materials provided with the distribution.
24 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
25 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
26 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
27 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
28 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34 * POSSIBILITY OF SUCH DAMAGE.
48 /* reroute stdout to /dev/null while returning another fd for the old stdout */
49 /* this is just for aesthetics: we don't want to see the output of 'ls' */
55 if ((fd
= fcntl(1, F_DUPFD
, 3)) == -1 || close(1) == -1) {
60 if ((fd2
= open("/dev/null", O_WRONLY
)) != 1) {
61 if (fd2
== -1 || dup2(fd2
, 1) != 1) {
73 restore_stdout(int fd
)
80 /* tests a simple posix_spawn executing /bin/ls */
82 test_posix_spawn_ls(void)
84 char * const args
[] = { "ls", "-la", NULL
};
87 err
= posix_spawn(NULL
, "/bin/ls", NULL
, NULL
, args
, NULL
);
92 /* tests a simple posix_spawnp executing ls via $PATH */
94 test_posix_spawnp_ls(void)
96 char * const args
[] = { "ls", "-la", NULL
};
99 err
= posix_spawnp(NULL
, "ls", NULL
, NULL
, args
, NULL
);
104 /* posix_spawn a non existant binary */
106 test_posix_spawn_missing(void)
108 char * const args
[] = { "t84_h_nonexist", NULL
};
111 err
= posix_spawn(NULL
, "../t84_h_nonexist", NULL
, NULL
, args
, NULL
);
116 /* posix_spawn a script with non existing interpreter */
118 test_posix_spawn_nonexec(void)
120 char * const args
[] = { "t84_h_nonexec", NULL
};
123 err
= posix_spawn(NULL
, "../t84_h_nonexec", NULL
, NULL
, args
, NULL
);
128 /* posix_spawn a child and get it's return code */
130 test_posix_spawn_child(void)
132 char * const args0
[] = { "t84_h_spawn", "0", NULL
};
133 char * const args1
[] = { "t84_h_spawn", "1", NULL
};
134 char * const args7
[] = { "t84_h_spawn", "7", NULL
};
138 err
= posix_spawn(&pid
, "../t84_h_spawn", NULL
, NULL
, args0
, NULL
);
139 if (err
!= 0 || pid
< 1)
141 waitpid(pid
, &status
, 0);
142 if (! (WIFEXITED(status
) && WEXITSTATUS(status
) == 0))
145 err
= posix_spawn(&pid
, "../t84_h_spawn", NULL
, NULL
, args1
, NULL
);
146 if (err
!= 0 || pid
< 1)
148 waitpid(pid
, &status
, 0);
149 if (! (WIFEXITED(status
) && WEXITSTATUS(status
) == 1))
152 err
= posix_spawn(&pid
, "../t84_h_spawn", NULL
, NULL
, args7
, NULL
);
153 if (err
!= 0 || pid
< 1)
155 waitpid(pid
, &status
, 0);
156 if (! (WIFEXITED(status
) && WEXITSTATUS(status
) == 7))
160 /* test spawn attributes */
162 test_posix_spawnattr(void)
164 int pid
, status
, err
, pfd
[2];
165 char helper_arg
[128];
166 char * const args
[] = { "t84_h_spawnattr", helper_arg
, NULL
};
168 posix_spawnattr_t attr
;
171 * create a pipe to controll the child
176 sprintf(helper_arg
, "%d", pfd
[0]);
178 posix_spawnattr_init(&attr
);
181 sigaddset(&sig
, SIGUSR1
);
183 posix_spawnattr_setflags(&attr
, POSIX_SPAWN_SETSCHEDULER
|
184 POSIX_SPAWN_SETSCHEDPARAM
| POSIX_SPAWN_SETPGROUP
|
185 POSIX_SPAWN_SETSIGMASK
| POSIX_SPAWN_SETSIGDEF
|
186 POSIX_SPAWN_SETSIGDEF
);
187 posix_spawnattr_setpgroup(&attr
, 0);
189 posix_spawnattr_setschedparam(&attr
, &sp
);
190 posix_spawnattr_setschedpolicy(&attr
, scheduler
);
192 posix_spawnattr_setsigmask(&attr
, &sig
);
193 posix_spawnattr_setsigdefault(&attr
, &sig
);
195 err
= posix_spawn(&pid
, "../t84_h_spawnattr", NULL
, &attr
, args
, NULL
);
199 /* ready, let child go */
200 write(pfd
[1], "q", 1);
204 /* wait and check result from child */
205 waitpid(pid
, &status
, 0);
206 if (! (WIFEXITED(status
) && WEXITSTATUS(status
) == EXIT_SUCCESS
))
209 posix_spawnattr_destroy(&attr
);
212 /* tests a simple posix_spawn executing /bin/ls with file actions */
214 test_posix_spawn_file_actions(void)
216 char * const args
[] = { "ls", "-la", NULL
};
218 posix_spawn_file_actions_t file_actions
;
221 * Just do a bunch of random operations which should leave console
224 posix_spawn_file_actions_init(&file_actions
);
225 posix_spawn_file_actions_adddup2(&file_actions
, 1, 3);
226 posix_spawn_file_actions_adddup2(&file_actions
, 1, 4);
227 posix_spawn_file_actions_adddup2(&file_actions
, 1, 6);
228 posix_spawn_file_actions_adddup2(&file_actions
, 1, 5);
229 posix_spawn_file_actions_addclose(&file_actions
, 3);
230 posix_spawn_file_actions_addclose(&file_actions
, 4);
231 posix_spawn_file_actions_addclose(&file_actions
, 6);
232 posix_spawn_file_actions_addclose(&file_actions
, 5);
234 posix_spawn_file_actions_addclose(&file_actions
, 0);
235 posix_spawn_file_actions_addclose(&file_actions
, 2);
236 posix_spawn_file_actions_addopen(&file_actions
, 0, "/dev/null",
238 posix_spawn_file_actions_adddup2(&file_actions
, 1, 2);
239 posix_spawn_file_actions_addclose(&file_actions
, 1);
240 posix_spawn_file_actions_adddup2(&file_actions
, 2, 1);
242 err
= posix_spawn(NULL
, "/bin/ls", &file_actions
, NULL
, args
, NULL
);
243 posix_spawn_file_actions_destroy(&file_actions
);
249 /* tests failures with file actions */
251 test_posix_spawn_file_actions_failures(void)
253 char * const args
[] = { "ls", "-la", NULL
};
255 posix_spawn_file_actions_t file_actions
;
257 /* Test bogus open */
258 posix_spawn_file_actions_init(&file_actions
);
259 posix_spawn_file_actions_addclose(&file_actions
, 0);
260 posix_spawn_file_actions_addopen(&file_actions
, 0, "t84_h_nonexist",
263 err
= posix_spawn(NULL
, "/bin/ls", &file_actions
, NULL
, args
, NULL
);
264 posix_spawn_file_actions_destroy(&file_actions
);
269 /* Test bogus dup2 */
270 for (i
= 3; i
< 10; i
++) {
271 posix_spawn_file_actions_init(&file_actions
);
272 posix_spawn_file_actions_adddup2(&file_actions
, i
, i
+1);
274 err
= posix_spawn(NULL
, "/bin/ls", &file_actions
, NULL
, args
,
276 posix_spawn_file_actions_destroy(&file_actions
);
283 * Test bogus exec with dup2 (to mess with the pipe error reporting in
286 posix_spawn_file_actions_init(&file_actions
);
287 posix_spawn_file_actions_adddup2(&file_actions
, 1, 3);
288 posix_spawn_file_actions_adddup2(&file_actions
, 1, 4);
289 posix_spawn_file_actions_adddup2(&file_actions
, 1, 6);
290 posix_spawn_file_actions_adddup2(&file_actions
, 1, 5);
291 posix_spawn_file_actions_adddup2(&file_actions
, 1, 7);
293 err
= posix_spawn(NULL
, "t84_h_nonexist", &file_actions
, NULL
, args
,
295 posix_spawn_file_actions_destroy(&file_actions
);
310 test_posix_spawn_ls();
311 test_posix_spawnp_ls();
314 test_posix_spawn_missing();
315 test_posix_spawn_nonexec();
318 test_posix_spawn_child();
321 test_posix_spawnattr();
324 test_posix_spawn_file_actions();
327 test_posix_spawn_file_actions_failures();
329 /* TODO: Write/port more tests */