Remove building with NOCRYPTO option
[minix.git] / minix / tests / test84.c
blob68f571f3ec45284172e5a7f7beb93047792e22d8
1 /*
2 * Based off tests/lib/libc/gen/posix_spawn/t_spawn.c
3 */
5 /* $NetBSD: t_spawn.c,v 1.1 2012/02/13 21:03:08 martin Exp $ */
7 /*-
8 * Copyright (c) 2012 The NetBSD Foundation, Inc.
9 * All rights reserved.
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
17 * are met:
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.
37 #include <fcntl.h>
38 #include <signal.h>
39 #include <spawn.h>
40 #include <string.h>
41 #include <stdio.h>
42 #include <stdlib.h>
43 #include <errno.h>
44 #include <sys/wait.h>
46 #include "common.h"
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' */
50 static int
51 sink_stdout(void)
53 int fd, fd2;
55 if ((fd = fcntl(1, F_DUPFD, 3)) == -1 || close(1) == -1) {
56 e(0);
57 quit();
60 if ((fd2 = open("/dev/null", O_WRONLY)) != 1) {
61 if (fd2 == -1 || dup2(fd2, 1) != 1) {
62 dup2(fd, 1);
63 e(0);
64 quit();
68 return fd;
71 /* restore stdout */
72 static void
73 restore_stdout(int fd)
76 dup2(fd, 1);
77 close(fd);
80 /* tests a simple posix_spawn executing /bin/ls */
81 static void
82 test_posix_spawn_ls(void)
84 char * const args[] = { "ls", "-la", NULL };
85 int err;
87 err = posix_spawn(NULL, "/bin/ls", NULL, NULL, args, NULL);
88 if (err != 0)
89 e(1);
92 /* tests a simple posix_spawnp executing ls via $PATH */
93 static void
94 test_posix_spawnp_ls(void)
96 char * const args[] = { "ls", "-la", NULL };
97 int err;
99 err = posix_spawnp(NULL, "ls", NULL, NULL, args, NULL);
100 if(err != 0)
101 e(2);
104 /* posix_spawn a non existant binary */
105 static void
106 test_posix_spawn_missing(void)
108 char * const args[] = { "t84_h_nonexist", NULL };
109 int err;
111 err = posix_spawn(NULL, "../t84_h_nonexist", NULL, NULL, args, NULL);
112 if (err != ENOENT)
113 e(4);
116 /* posix_spawn a script with non existing interpreter */
117 static void
118 test_posix_spawn_nonexec(void)
120 char * const args[] = { "t84_h_nonexec", NULL };
121 int err;
123 err = posix_spawn(NULL, "../t84_h_nonexec", NULL, NULL, args, NULL);
124 if (err != ENOENT)
125 e(5);
128 /* posix_spawn a child and get it's return code */
129 static void
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 };
135 int err, status;
136 pid_t pid;
138 err = posix_spawn(&pid, "../t84_h_spawn", NULL, NULL, args0, NULL);
139 if (err != 0 || pid < 1)
140 e(1);
141 waitpid(pid, &status, 0);
142 if (! (WIFEXITED(status) && WEXITSTATUS(status) == 0))
143 e(2);
145 err = posix_spawn(&pid, "../t84_h_spawn", NULL, NULL, args1, NULL);
146 if (err != 0 || pid < 1)
147 e(3);
148 waitpid(pid, &status, 0);
149 if (! (WIFEXITED(status) && WEXITSTATUS(status) == 1))
150 e(4);
152 err = posix_spawn(&pid, "../t84_h_spawn", NULL, NULL, args7, NULL);
153 if (err != 0 || pid < 1)
154 e(5);
155 waitpid(pid, &status, 0);
156 if (! (WIFEXITED(status) && WEXITSTATUS(status) == 7))
157 e(6);
160 /* test spawn attributes */
161 static void
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 };
167 sigset_t sig;
168 posix_spawnattr_t attr;
171 * create a pipe to controll the child
173 err = pipe(pfd);
174 if (err != 0)
175 e(1);
176 sprintf(helper_arg, "%d", pfd[0]);
178 posix_spawnattr_init(&attr);
180 sigemptyset(&sig);
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);
188 #if 0
189 posix_spawnattr_setschedparam(&attr, &sp);
190 posix_spawnattr_setschedpolicy(&attr, scheduler);
191 #endif
192 posix_spawnattr_setsigmask(&attr, &sig);
193 posix_spawnattr_setsigdefault(&attr, &sig);
195 err = posix_spawn(&pid, "../t84_h_spawnattr", NULL, &attr, args, NULL);
196 if (err != 0)
197 e(2);
199 /* ready, let child go */
200 write(pfd[1], "q", 1);
201 close(pfd[0]);
202 close(pfd[1]);
204 /* wait and check result from child */
205 waitpid(pid, &status, 0);
206 if (! (WIFEXITED(status) && WEXITSTATUS(status) == EXIT_SUCCESS))
207 e(3);
209 posix_spawnattr_destroy(&attr);
212 /* tests a simple posix_spawn executing /bin/ls with file actions */
213 static void
214 test_posix_spawn_file_actions(void)
216 char * const args[] = { "ls", "-la", NULL };
217 int err;
218 posix_spawn_file_actions_t file_actions;
221 * Just do a bunch of random operations which should leave console
222 * output intact.
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",
237 O_RDONLY, 0);
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);
245 if (err != 0)
246 e(1);
249 /* tests failures with file actions */
250 static void
251 test_posix_spawn_file_actions_failures(void)
253 char * const args[] = { "ls", "-la", NULL };
254 int err, i;
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",
261 O_RDONLY, 0);
263 err = posix_spawn(NULL, "/bin/ls", &file_actions, NULL, args, NULL);
264 posix_spawn_file_actions_destroy(&file_actions);
266 if (err == 0)
267 e(1);
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,
275 NULL);
276 posix_spawn_file_actions_destroy(&file_actions);
278 if (err == 0)
279 e(i-2);
283 * Test bogus exec with dup2 (to mess with the pipe error reporting in
284 * posix_spawn.c)
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,
294 NULL);
295 posix_spawn_file_actions_destroy(&file_actions);
297 if (err == 0)
298 e(9);
302 main(void)
304 int fd;
306 start(84);
308 subtest = 1;
309 fd = sink_stdout();
310 test_posix_spawn_ls();
311 test_posix_spawnp_ls();
312 restore_stdout(fd);
314 test_posix_spawn_missing();
315 test_posix_spawn_nonexec();
317 subtest = 2;
318 test_posix_spawn_child();
320 subtest = 3;
321 test_posix_spawnattr();
322 subtest = 4;
323 fd = sink_stdout();
324 test_posix_spawn_file_actions();
325 restore_stdout(fd);
326 subtest = 5;
327 test_posix_spawn_file_actions_failures();
329 /* TODO: Write/port more tests */
331 quit();
333 /* Not reached */
334 return -1;