Mercurial > gnulib
annotate tests/test-posix_spawn2.c @ 40057:b06060465f09
maint: Run 'make update-copyright'
author | Paul Eggert <eggert@cs.ucla.edu> |
---|---|
date | Tue, 01 Jan 2019 00:25:11 +0100 |
parents | cd549182ef0e |
children |
rev | line source |
---|---|
10547 | 1 /* Test of posix_spawn() function. |
40057
b06060465f09
maint: Run 'make update-copyright'
Paul Eggert <eggert@cs.ucla.edu>
parents:
39883
diff
changeset
|
2 Copyright (C) 2008-2019 Free Software Foundation, Inc. |
10547 | 3 |
4 This program is free software: you can redistribute it and/or modify | |
5 it under the terms of the GNU General Public License as published by | |
6 the Free Software Foundation; either version 3 of the License, or | |
7 (at your option) any later version. | |
8 | |
9 This program is distributed in the hope that it will be useful, | |
10 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 GNU General Public License for more details. | |
13 | |
14 You should have received a copy of the GNU General Public License | |
19190 | 15 along with this program. If not, see <https://www.gnu.org/licenses/>. */ |
10547 | 16 |
17 /* Written by Bruno Haible <bruno@clisp.org>, 2008. */ | |
18 | |
19 #include <config.h> | |
20 | |
21 #include <spawn.h> | |
22 | |
23 #include <errno.h> | |
24 #include <fcntl.h> | |
25 #include <signal.h> | |
26 #include <stdbool.h> | |
27 #include <stdio.h> | |
28 #include <stdlib.h> | |
29 #include <string.h> | |
30 #include <unistd.h> | |
31 #include <sys/types.h> | |
32 #include <sys/wait.h> | |
33 | |
34 #define CHILD_PROGRAM_FILENAME "test-posix_spawn2.sh" | |
35 | |
36 static int | |
37 fd_safer (int fd) | |
38 { | |
39 if (0 <= fd && fd <= 2) | |
40 { | |
41 int f = fd_safer (dup (fd)); | |
42 int e = errno; | |
43 close (fd); | |
44 errno = e; | |
45 fd = f; | |
46 } | |
47 | |
48 return fd; | |
10548 | 49 } |
10547 | 50 |
51 int | |
52 main () | |
53 { | |
39883 | 54 char *argv[3] = { (char *) BOURNE_SHELL, (char *) CHILD_PROGRAM_FILENAME, NULL }; |
10547 | 55 int ofd[2]; |
56 sigset_t blocked_signals; | |
57 sigset_t fatal_signal_set; | |
58 posix_spawn_file_actions_t actions; | |
59 bool actions_allocated; | |
60 posix_spawnattr_t attrs; | |
61 bool attrs_allocated; | |
62 int err; | |
63 pid_t child; | |
64 int fd; | |
65 FILE *fp; | |
66 int written; | |
67 int status; | |
68 int exitstatus; | |
69 | |
70 if (pipe (ofd) < 0 || (ofd[1] = fd_safer (ofd[1])) < 0) | |
71 { | |
72 perror ("cannot create pipe"); | |
73 exit (1); | |
74 } | |
75 sigprocmask (SIG_SETMASK, NULL, &blocked_signals); | |
76 sigemptyset (&fatal_signal_set); | |
77 sigaddset (&fatal_signal_set, SIGINT); | |
78 sigaddset (&fatal_signal_set, SIGTERM); | |
79 sigaddset (&fatal_signal_set, SIGHUP); | |
80 sigaddset (&fatal_signal_set, SIGPIPE); | |
81 sigprocmask (SIG_BLOCK, &fatal_signal_set, NULL); | |
82 actions_allocated = false; | |
83 attrs_allocated = false; | |
84 if ((err = posix_spawn_file_actions_init (&actions)) != 0 | |
85 || (actions_allocated = true, | |
86 (err = posix_spawn_file_actions_adddup2 (&actions, ofd[0], STDIN_FILENO)) != 0 | |
87 || (err = posix_spawn_file_actions_addclose (&actions, ofd[0])) != 0 | |
88 || (err = posix_spawn_file_actions_addclose (&actions, ofd[1])) != 0 | |
89 || (err = posix_spawnattr_init (&attrs)) != 0 | |
90 || (attrs_allocated = true, | |
91 (err = posix_spawnattr_setsigmask (&attrs, &blocked_signals)) != 0 | |
92 || (err = posix_spawnattr_setflags (&attrs, POSIX_SPAWN_SETSIGMASK)) != 0) | |
39883 | 93 || (err = posix_spawnp (&child, BOURNE_SHELL, &actions, &attrs, argv, environ)) != 0)) |
10547 | 94 { |
95 if (actions_allocated) | |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11049
diff
changeset
|
96 posix_spawn_file_actions_destroy (&actions); |
10547 | 97 if (attrs_allocated) |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
11049
diff
changeset
|
98 posix_spawnattr_destroy (&attrs); |
10547 | 99 sigprocmask (SIG_UNBLOCK, &fatal_signal_set, NULL); |
100 errno = err; | |
101 perror ("subprocess failed"); | |
102 exit (1); | |
103 } | |
104 posix_spawn_file_actions_destroy (&actions); | |
105 posix_spawnattr_destroy (&attrs); | |
106 sigprocmask (SIG_UNBLOCK, &fatal_signal_set, NULL); | |
107 close (ofd[0]); | |
108 fd = ofd[1]; | |
109 fp = fdopen (fd, "w"); | |
110 if (fp == NULL) | |
111 { | |
112 fprintf (stderr, "fdopen() failed\n"); | |
113 exit (1); | |
114 } | |
115 written = fwrite ("Halle Potta\n", 1, 12, fp); | |
116 if (written < 12) | |
117 { | |
118 fprintf (stderr, "could not write input\n"); | |
119 exit (1); | |
120 } | |
121 fclose (fp); | |
122 status = 0; | |
123 while (waitpid (child, &status, 0) != child) | |
124 ; | |
125 if (!WIFEXITED (status)) | |
126 { | |
127 fprintf (stderr, "subprocess terminated with unexpected wait status %d\n", status); | |
128 exit (1); | |
129 } | |
130 exitstatus = WEXITSTATUS (status); | |
131 if (exitstatus != 0) | |
132 { | |
133 fprintf (stderr, "subprocess terminated with unexpected exit status %d\n", exitstatus); | |
134 exit (1); | |
135 } | |
136 return 0; | |
137 } |