This source file includes following definitions.
- main
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 #include <config.h>
18
19 #include "execute.h"
20
21 #include <errno.h>
22 #include <fcntl.h>
23 #include <signal.h>
24 #include <stdbool.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <unistd.h>
29 #include <sys/stat.h>
30
31 #if defined _WIN32 && ! defined __CYGWIN__
32
33 # include <io.h>
34 #endif
35
36 #include "read-file.h"
37 #include "macros.h"
38
39
40 #if defined _WIN32 && ! defined __CYGWIN__
41
42 # define DEV_NULL "NUL"
43 #else
44
45 # define DEV_NULL "/dev/null"
46 #endif
47
48 #define BASE "test-execute"
49
50 int
51 main (int argc, char *argv[])
52 {
53 if (argc != 3)
54 {
55 fprintf (stderr, "%s: need 2 arguments\n", argv[0]);
56 return 2;
57 }
58 char *prog_path = argv[1];
59 const char *progname = "test-execute-child";
60 int test = atoi (argv[2]);
61
62 switch (test)
63 {
64 case 14:
65 case 15:
66 case 16:
67
68
69
70
71
72
73
74
75 #if HAVE_CLOSE_RANGE
76 if (close_range (3, 20 - 1, 0) < 0)
77 #endif
78 {
79 int fd;
80 for (fd = 3; fd < 20; fd++)
81 close (fd);
82 }
83 default:
84 break;
85 }
86
87 switch (test)
88 {
89 case 0:
90 {
91
92 const char *prog_argv[2] = { prog_path, NULL };
93 int ret = execute (progname, prog_argv[0], prog_argv, NULL,
94 false, false, false, false, true, false, NULL);
95 ASSERT (ret == 40);
96 }
97 break;
98 case 1:
99 {
100
101 const char *prog_argv[3] = { "./non-existent", NULL };
102 int ret = execute (progname, prog_argv[0], prog_argv, NULL,
103 false, false, false, false, true, false, NULL);
104 ASSERT (ret == 127);
105 }
106 break;
107 case 2:
108 {
109
110 const char *prog_argv[13] =
111 {
112 prog_path,
113 "2",
114 "abc def",
115 "abc\"def\"ghi",
116 "xyz\"",
117 "abc\\def\\ghi",
118 "xyz\\",
119 "???",
120 "***",
121 "",
122 "foo",
123 "",
124 NULL
125 };
126 int ret = execute (progname, prog_argv[0], prog_argv, NULL,
127 false, false, false, false, true, false, NULL);
128 ASSERT (ret == 0);
129 }
130 break;
131 case 3:
132 #if !(defined _WIN32 && !defined __CYGWIN__)
133 {
134
135 const char *prog_argv[3] = { prog_path, "3", NULL };
136 int termsig = 0x7DEADBEE;
137 int ret = execute (progname, prog_argv[0], prog_argv, NULL,
138 false, false, false, false, true, false, &termsig);
139 ASSERT (ret == 127);
140 ASSERT (termsig == SIGPIPE);
141 }
142 #endif
143 break;
144 case 4:
145 #if !(defined _WIN32 && !defined __CYGWIN__)
146 {
147
148 const char *prog_argv[3] = { prog_path, "4", NULL };
149 int termsig = 0x7DEADBEE;
150 int ret = execute (progname, prog_argv[0], prog_argv, NULL,
151 true, false, false, false, true, false, &termsig);
152 ASSERT (ret == 0);
153 ASSERT (termsig == SIGPIPE);
154 }
155 #endif
156 break;
157 case 5:
158 {
159
160 const char *prog_argv[3] = { prog_path, "5", NULL };
161 int termsig = 0x7DEADBEE;
162 int ret = execute (progname, prog_argv[0], prog_argv, NULL,
163 false, false, false, false, true, false, &termsig);
164 ASSERT (ret == 127);
165 #if defined _WIN32 && !defined __CYGWIN__
166 ASSERT (termsig == SIGTERM);
167 #else
168 ASSERT (termsig == SIGINT);
169 #endif
170 }
171 break;
172 case 6:
173 {
174
175 FILE *fp = fopen (BASE ".tmp", "w");
176 fputs ("Foo", fp);
177 ASSERT (fclose (fp) == 0);
178
179 fp = freopen (BASE ".tmp", "r", stdin);
180 ASSERT (fp != NULL);
181
182 const char *prog_argv[3] = { prog_path, "6", NULL };
183 int ret = execute (progname, prog_argv[0], prog_argv, NULL,
184 false, false, false, false, true, false, NULL);
185 ASSERT (ret == 0);
186
187 ASSERT (fclose (stdin) == 0);
188 ASSERT (remove (BASE ".tmp") == 0);
189 }
190 break;
191 case 7:
192 {
193
194 FILE *fp = fopen (BASE ".tmp", "w");
195 fputs ("Foo", fp);
196 ASSERT (fclose (fp) == 0);
197
198 fp = freopen (BASE ".tmp", "r", stdin);
199 ASSERT (fp != NULL);
200
201 const char *prog_argv[3] = { prog_path, "7", NULL };
202 int ret = execute (progname, prog_argv[0], prog_argv, NULL,
203 false, true, false, false, true, false, NULL);
204 ASSERT (ret == 0);
205
206 ASSERT (fclose (stdin) == 0);
207 ASSERT (remove (BASE ".tmp") == 0);
208 }
209 break;
210 case 8:
211 {
212
213 FILE *fp = freopen (BASE ".tmp", "w", stdout);
214 ASSERT (fp != NULL);
215
216 const char *prog_argv[3] = { prog_path, "8", NULL };
217 int ret = execute (progname, prog_argv[0], prog_argv, NULL,
218 false, false, false, false, true, false, NULL);
219 ASSERT (ret == 0);
220
221 ASSERT (fclose (stdout) == 0);
222
223 size_t length;
224 char *contents = read_file (BASE ".tmp", 0, &length);
225 ASSERT (length == 3 && memcmp (contents, "bar", 3) == 0);
226
227 ASSERT (remove (BASE ".tmp") == 0);
228 }
229 break;
230 case 9:
231 {
232
233 FILE *fp = freopen (DEV_NULL, "w", stdout);
234 ASSERT (fp != NULL);
235
236 const char *prog_argv[3] = { prog_path, "9", NULL };
237 int ret = execute (progname, prog_argv[0], prog_argv, NULL,
238 false, false, false, false, true, false, NULL);
239 ASSERT (ret == 0);
240 }
241 break;
242 case 10:
243 {
244
245 FILE *fp = freopen (BASE ".tmp", "w", stdout);
246 ASSERT (fp != NULL);
247
248 const char *prog_argv[3] = { prog_path, "10", NULL };
249 int ret = execute (progname, prog_argv[0], prog_argv, NULL,
250 false, false, true, false, true, false, NULL);
251 ASSERT (ret == 0);
252
253 ASSERT (fclose (stdout) == 0);
254
255 size_t length;
256 (void) read_file (BASE ".tmp", 0, &length);
257 ASSERT (length == 0);
258
259 ASSERT (remove (BASE ".tmp") == 0);
260 }
261 break;
262 case 11:
263 {
264
265 FILE *fp = freopen (BASE ".tmp", "w", stderr);
266 ASSERT (fp != NULL);
267
268 const char *prog_argv[3] = { prog_path, "11", NULL };
269 int ret = execute (progname, prog_argv[0], prog_argv, NULL,
270 false, false, false, false, true, false, NULL);
271 ASSERT (ret == 0);
272
273 ASSERT (fclose (stderr) == 0);
274
275 size_t length;
276 char *contents = read_file (BASE ".tmp", 0, &length);
277 ASSERT (length == 3 && memcmp (contents, "bar", 3) == 0);
278
279 ASSERT (remove (BASE ".tmp") == 0);
280 }
281 break;
282 case 12:
283 {
284
285 FILE *fp = freopen (DEV_NULL, "w", stderr);
286 ASSERT (fp != NULL);
287
288 const char *prog_argv[3] = { prog_path, "12", NULL };
289 int ret = execute (progname, prog_argv[0], prog_argv, NULL,
290 false, false, false, false, true, false, NULL);
291 ASSERT (ret == 0);
292 }
293 break;
294 case 13:
295 {
296
297 FILE *fp = freopen (BASE ".tmp", "w", stderr);
298 ASSERT (fp != NULL);
299
300 const char *prog_argv[3] = { prog_path, "13", NULL };
301 int ret = execute (progname, prog_argv[0], prog_argv, NULL,
302 false, false, false, true, true, false, NULL);
303 ASSERT (ret == 0);
304
305 ASSERT (fclose (stderr) == 0);
306
307 size_t length;
308 (void) read_file (BASE ".tmp", 0, &length);
309 ASSERT (length == 0);
310
311 ASSERT (remove (BASE ".tmp") == 0);
312 }
313 break;
314 case 14:
315 {
316
317 ASSERT (dup2 (STDOUT_FILENO, 10) >= 0);
318 const char *prog_argv[3] = { prog_path, "14", NULL };
319 int ret = execute (progname, prog_argv[0], prog_argv, NULL,
320 true, false, false, false, true, false, NULL);
321 ASSERT (ret == 0);
322 }
323 break;
324 case 15:
325 {
326
327 ASSERT (fcntl (STDOUT_FILENO, F_DUPFD, 10) >= 0);
328 const char *prog_argv[3] = { prog_path, "15", NULL };
329 int ret = execute (progname, prog_argv[0], prog_argv, NULL,
330 true, false, false, false, true, false, NULL);
331 ASSERT (ret == 0);
332 }
333 break;
334 case 16:
335 {
336
337 ASSERT (fcntl (STDOUT_FILENO, F_DUPFD_CLOEXEC, 10) >= 0);
338 const char *prog_argv[3] = { prog_path, "16", NULL };
339 int ret = execute (progname, prog_argv[0], prog_argv, NULL,
340 true, false, false, false, true, false, NULL);
341 ASSERT (ret == 0);
342 }
343 break;
344 case 17:
345 {
346
347
348 FILE *fp = fopen (BASE ".tmp", "w");
349 fputs ("Foobar", fp);
350 ASSERT (fclose (fp) == 0);
351
352 int fd = open (BASE ".tmp", O_RDONLY);
353 ASSERT (fd >= 0 && fd < 10);
354
355 ASSERT (dup2 (fd, 10) >= 0);
356 close (fd);
357 fd = 10;
358
359 char buf[2];
360 ASSERT (read (fd, buf, sizeof (buf)) == sizeof (buf));
361
362
363 const char *prog_argv[3] = { prog_path, "17", NULL };
364 int ret = execute (progname, prog_argv[0], prog_argv, NULL,
365 false, false, false, false, true, false, NULL);
366 ASSERT (ret == 0);
367
368 close (fd);
369 ASSERT (remove (BASE ".tmp") == 0);
370 }
371 break;
372 case 18:
373 {
374
375
376 remove (BASE ".tmp");
377 int fd = open (BASE ".tmp", O_RDWR | O_CREAT | O_TRUNC, 0600);
378 ASSERT (fd >= 0 && fd < 10);
379
380 ASSERT (dup2 (fd, 10) >= 0);
381 close (fd);
382 fd = 10;
383
384 ASSERT (write (fd, "Foo", 3) == 3);
385
386
387 const char *prog_argv[3] = { prog_path, "18", NULL };
388 int ret = execute (progname, prog_argv[0], prog_argv, NULL,
389 false, false, false, false, true, false, NULL);
390 ASSERT (ret == 0);
391
392 close (fd);
393
394 size_t length;
395 char *contents = read_file (BASE ".tmp", 0, &length);
396 ASSERT (length == 6 && memcmp (contents, "Foobar", 6) == 0);
397
398 ASSERT (remove (BASE ".tmp") == 0);
399 }
400 break;
401 case 19:
402 {
403
404
405 FILE *fp = fopen (BASE ".tmp", "w");
406 fputs ("Foo", fp);
407 ASSERT (fclose (fp) == 0);
408
409 int fd_in = open (BASE ".tmp", O_RDONLY);
410 ASSERT (fd_in >= 0 && fd_in < 10);
411
412 int fd_out = open (BASE ".tmp", O_WRONLY | O_APPEND);
413 ASSERT (fd_out >= 0 && fd_out < 10);
414
415 ASSERT (dup2 (fd_in, 10) >= 0);
416 close (fd_in);
417 fd_in = 10;
418
419 ASSERT (dup2 (fd_out, 11) >= 0);
420 close (fd_out);
421 fd_out = 11;
422
423 const char *prog_argv[3] = { prog_path, "19", NULL };
424 int ret = execute (progname, prog_argv[0], prog_argv, NULL,
425 false, false, false, false, true, false, NULL);
426 #if defined _WIN32 && ! defined __CYGWIN__
427 ASSERT (ret == 4 + 2 * (_isatty (10) != 0) + (_isatty (11) != 0));
428 #else
429 ASSERT (ret == 4 + 2 * (isatty (10) != 0) + (isatty (11) != 0));
430 #endif
431
432 close (fd_in);
433 close (fd_out);
434 ASSERT (remove (BASE ".tmp") == 0);
435 }
436 break;
437 case 20:
438 {
439
440
441 ASSERT (dup2 (STDIN_FILENO, 10) >= 0);
442 int fd_in = 10;
443
444 ASSERT (dup2 (STDOUT_FILENO, 11) >= 0);
445 int fd_out = 11;
446
447 const char *prog_argv[3] = { prog_path, "20", NULL };
448 int ret = execute (progname, prog_argv[0], prog_argv, NULL,
449 false, false, false, false, true, false, NULL);
450 #if defined _WIN32 && ! defined __CYGWIN__
451 ASSERT (ret == 4 + 2 * (_isatty (10) != 0) + (_isatty (11) != 0));
452 #else
453 ASSERT (ret == 4 + 2 * (isatty (10) != 0) + (isatty (11) != 0));
454 #endif
455
456 close (fd_in);
457 close (fd_out);
458 }
459 break;
460 case 21:
461 {
462
463 rmdir (BASE ".sub");
464 ASSERT (mkdir (BASE ".sub", 0700) == 0);
465
466 char cwd[1024];
467 #if defined _WIN32 && ! defined __CYGWIN__
468 ASSERT (_getcwd (cwd, sizeof (cwd)) != NULL);
469 #else
470 ASSERT (getcwd (cwd, sizeof (cwd)) != NULL);
471 #endif
472
473 const char *prog_argv[4] = { prog_path, "21", cwd, NULL };
474 int ret = execute (progname, prog_argv[0], prog_argv, BASE ".sub",
475 false, false, false, false, true, false, NULL);
476 ASSERT (ret == 0);
477
478 ASSERT (rmdir (BASE ".sub") == 0);
479 }
480 break;
481 default:
482 ASSERT (false);
483 }
484 return 0;
485 }