Mercurial > hg > octave-kai > gnulib-hg
annotate lib/execute.c @ 11653:ecb384fccb5b
fpurge: migrate into <stdio.h>
* lib/fpurge.h: Delete...
* lib/stdio.in.h (fpurge): ...and declare here, instead.
* lib/fpurge.c (fpurge): Change declaring header.
* modules/fpurge (Files): Drop deleted file.
(Depends-on): Add stdio.
(configure.ac): Set witness.
* modules/stdio (Makefile.am): Support fpurge macros.
* m4/stdio_h.m4 (gl_STDIO_H_DEFAULTS): Likewise.
* m4/fpurge.m4 (gl_FUNC_FPURGE): Set appropriate variables.
* lib/fflush.c: Update client.
* tests/test-fpurge.c: Likewise.
* NEWS: Mention the change.
Signed-off-by: Eric Blake <ebb9@byu.net>
author | Eric Blake <ebb9@byu.net> |
---|---|
date | Wed, 24 Jun 2009 06:49:00 -0600 |
parents | 16ae9ebb84d9 |
children | 21991b412914 |
rev | line source |
---|---|
4936 | 1 /* Creation of autonomous subprocesses. |
11049
8398d9f607b4
unistd: guarantee STDIN_FILENO here, for OS/2 EMX
Eric Blake <ebb9@byu.net>
parents:
10546
diff
changeset
|
2 Copyright (C) 2001-2004, 2006-2009 Free Software Foundation, Inc. |
4936 | 3 Written by Bruno Haible <haible@clisp.cons.org>, 2001. |
4 | |
9309
bbbbbf4cd1c5
Change copyright notice from GPLv2+ to GPLv3+.
Bruno Haible <bruno@clisp.org>
parents:
8196
diff
changeset
|
5 This program is free software: you can redistribute it and/or modify |
4936 | 6 it under the terms of the GNU General Public License as published by |
9309
bbbbbf4cd1c5
Change copyright notice from GPLv2+ to GPLv3+.
Bruno Haible <bruno@clisp.org>
parents:
8196
diff
changeset
|
7 the Free Software Foundation; either version 3 of the License, or |
bbbbbf4cd1c5
Change copyright notice from GPLv2+ to GPLv3+.
Bruno Haible <bruno@clisp.org>
parents:
8196
diff
changeset
|
8 (at your option) any later version. |
4936 | 9 |
10 This program is distributed in the hope that it will be useful, | |
11 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 GNU General Public License for more details. | |
14 | |
15 You should have received a copy of the GNU General Public License | |
9309
bbbbbf4cd1c5
Change copyright notice from GPLv2+ to GPLv3+.
Bruno Haible <bruno@clisp.org>
parents:
8196
diff
changeset
|
16 along with this program. If not, see <http://www.gnu.org/licenses/>. */ |
4936 | 17 |
18 | |
7304
1c4ed7637c24
Include <config.h> unconditionally.
Bruno Haible <bruno@clisp.org>
parents:
6761
diff
changeset
|
19 #include <config.h> |
4936 | 20 |
21 /* Specification. */ | |
22 #include "execute.h" | |
23 | |
24 #include <errno.h> | |
25 #include <fcntl.h> | |
26 #include <stdbool.h> | |
27 #include <stdlib.h> | |
28 #include <signal.h> | |
6751
1b0092424a44
Include <unistd.h> unconditionally.
Bruno Haible <bruno@clisp.org>
parents:
5848
diff
changeset
|
29 #include <unistd.h> |
4936 | 30 |
31 #include "error.h" | |
32 #include "fatal-signal.h" | |
33 #include "wait-process.h" | |
34 #include "gettext.h" | |
35 | |
36 #define _(str) gettext (str) | |
37 | |
38 #if defined _MSC_VER || defined __MINGW32__ | |
39 | |
40 /* Native Woe32 API. */ | |
41 # include <process.h> | |
42 # include "w32spawn.h" | |
43 | |
44 #else | |
45 | |
46 /* Unix API. */ | |
11090
414a549bcd8b
Use the posix_spawn or its replacement on all Unix platforms.
Bruno Haible <bruno@clisp.org>
parents:
11049
diff
changeset
|
47 # include <spawn.h> |
4936 | 48 |
49 #endif | |
50 | |
7863 | 51 /* The results of open() in this file are not used with fchdir, |
52 therefore save some unnecessary work in fchdir.c. */ | |
53 #undef open | |
54 #undef close | |
55 | |
4936 | 56 |
57 #ifdef EINTR | |
58 | |
59 /* EINTR handling for close(), open(). | |
60 These functions can return -1/EINTR even though we don't have any | |
61 signal handlers set up, namely when we get interrupted via SIGSTOP. */ | |
62 | |
63 static inline int | |
64 nonintr_close (int fd) | |
65 { | |
66 int retval; | |
67 | |
68 do | |
69 retval = close (fd); | |
70 while (retval < 0 && errno == EINTR); | |
71 | |
72 return retval; | |
73 } | |
74 #define close nonintr_close | |
75 | |
76 static inline int | |
77 nonintr_open (const char *pathname, int oflag, mode_t mode) | |
78 { | |
79 int retval; | |
80 | |
81 do | |
82 retval = open (pathname, oflag, mode); | |
83 while (retval < 0 && errno == EINTR); | |
84 | |
85 return retval; | |
86 } | |
87 #undef open /* avoid warning on VMS */ | |
88 #define open nonintr_open | |
89 | |
90 #endif | |
91 | |
92 | |
93 /* Execute a command, optionally redirecting any of the three standard file | |
94 descriptors to /dev/null. Return its exit code. | |
95 If it didn't terminate correctly, exit if exit_on_error is true, otherwise | |
96 return 127. | |
97 If slave_process is true, the child process will be terminated when its | |
98 creator receives a catchable fatal signal. */ | |
99 int | |
100 execute (const char *progname, | |
101 const char *prog_path, char **prog_argv, | |
102 bool ignore_sigpipe, | |
103 bool null_stdin, bool null_stdout, bool null_stderr, | |
10197
d079dd7b69bc
Add termsigp argument to execute() and wait_process().
Bruno Haible <bruno@clisp.org>
parents:
9721
diff
changeset
|
104 bool slave_process, bool exit_on_error, |
d079dd7b69bc
Add termsigp argument to execute() and wait_process().
Bruno Haible <bruno@clisp.org>
parents:
9721
diff
changeset
|
105 int *termsigp) |
4936 | 106 { |
107 #if defined _MSC_VER || defined __MINGW32__ | |
108 | |
109 /* Native Woe32 API. */ | |
110 int orig_stdin; | |
111 int orig_stdout; | |
112 int orig_stderr; | |
113 int exitcode; | |
114 int nullinfd; | |
115 int nulloutfd; | |
116 | |
10544
cb17877a6ccd
Enable use of shell scripts as executables in mingw.
Bruno Haible <bruno@clisp.org>
parents:
10197
diff
changeset
|
117 /* FIXME: Need to free memory allocated by prepare_spawn. */ |
4936 | 118 prog_argv = prepare_spawn (prog_argv); |
119 | |
120 /* Save standard file handles of parent process. */ | |
121 if (null_stdin) | |
122 orig_stdin = dup_noinherit (STDIN_FILENO); | |
123 if (null_stdout) | |
124 orig_stdout = dup_noinherit (STDOUT_FILENO); | |
125 if (null_stderr) | |
126 orig_stderr = dup_noinherit (STDERR_FILENO); | |
127 exitcode = -1; | |
128 | |
129 /* Create standard file handles of child process. */ | |
130 nullinfd = -1; | |
131 nulloutfd = -1; | |
132 if ((!null_stdin | |
133 || ((nullinfd = open ("NUL", O_RDONLY, 0)) >= 0 | |
134 && (nullinfd == STDIN_FILENO | |
135 || (dup2 (nullinfd, STDIN_FILENO) >= 0 | |
136 && close (nullinfd) >= 0)))) | |
137 && (!(null_stdout || null_stderr) | |
138 || ((nulloutfd = open ("NUL", O_RDWR, 0)) >= 0 | |
139 && (!null_stdout | |
140 || nulloutfd == STDOUT_FILENO | |
141 || dup2 (nulloutfd, STDOUT_FILENO) >= 0) | |
142 && (!null_stderr | |
143 || nulloutfd == STDERR_FILENO | |
144 || dup2 (nulloutfd, STDERR_FILENO) >= 0) | |
145 && ((null_stdout && nulloutfd == STDOUT_FILENO) | |
146 || (null_stderr && nulloutfd == STDERR_FILENO) | |
147 || close (nulloutfd) >= 0)))) | |
10546
54ac6d458333
Propagate effects of putenv/setenv/unsetenv to child processes.
Bruno Haible <bruno@clisp.org>
parents:
10544
diff
changeset
|
148 /* Use spawnvpe and pass the environment explicitly. This is needed if |
54ac6d458333
Propagate effects of putenv/setenv/unsetenv to child processes.
Bruno Haible <bruno@clisp.org>
parents:
10544
diff
changeset
|
149 the program has modified the environment using putenv() or [un]setenv(). |
54ac6d458333
Propagate effects of putenv/setenv/unsetenv to child processes.
Bruno Haible <bruno@clisp.org>
parents:
10544
diff
changeset
|
150 On Windows, programs have two environments, one in the "environment |
54ac6d458333
Propagate effects of putenv/setenv/unsetenv to child processes.
Bruno Haible <bruno@clisp.org>
parents:
10544
diff
changeset
|
151 block" of the process and managed through SetEnvironmentVariable(), and |
54ac6d458333
Propagate effects of putenv/setenv/unsetenv to child processes.
Bruno Haible <bruno@clisp.org>
parents:
10544
diff
changeset
|
152 one inside the process, in the location retrieved by the 'environ' |
54ac6d458333
Propagate effects of putenv/setenv/unsetenv to child processes.
Bruno Haible <bruno@clisp.org>
parents:
10544
diff
changeset
|
153 macro. When using spawnvp() without 'e', the child process inherits a |
54ac6d458333
Propagate effects of putenv/setenv/unsetenv to child processes.
Bruno Haible <bruno@clisp.org>
parents:
10544
diff
changeset
|
154 copy of the environment block - ignoring the effects of putenv() and |
54ac6d458333
Propagate effects of putenv/setenv/unsetenv to child processes.
Bruno Haible <bruno@clisp.org>
parents:
10544
diff
changeset
|
155 [un]setenv(). */ |
10544
cb17877a6ccd
Enable use of shell scripts as executables in mingw.
Bruno Haible <bruno@clisp.org>
parents:
10197
diff
changeset
|
156 { |
11268 | 157 exitcode = spawnvpe (P_WAIT, prog_path, (const char **) prog_argv, |
158 (const char **) environ); | |
10544
cb17877a6ccd
Enable use of shell scripts as executables in mingw.
Bruno Haible <bruno@clisp.org>
parents:
10197
diff
changeset
|
159 if (exitcode < 0 && errno == ENOEXEC) |
cb17877a6ccd
Enable use of shell scripts as executables in mingw.
Bruno Haible <bruno@clisp.org>
parents:
10197
diff
changeset
|
160 { |
cb17877a6ccd
Enable use of shell scripts as executables in mingw.
Bruno Haible <bruno@clisp.org>
parents:
10197
diff
changeset
|
161 /* prog is not an native executable. Try to execute it as a |
cb17877a6ccd
Enable use of shell scripts as executables in mingw.
Bruno Haible <bruno@clisp.org>
parents:
10197
diff
changeset
|
162 shell script. Note that prepare_spawn() has already prepended |
cb17877a6ccd
Enable use of shell scripts as executables in mingw.
Bruno Haible <bruno@clisp.org>
parents:
10197
diff
changeset
|
163 a hidden element "sh.exe" to prog_argv. */ |
cb17877a6ccd
Enable use of shell scripts as executables in mingw.
Bruno Haible <bruno@clisp.org>
parents:
10197
diff
changeset
|
164 --prog_argv; |
11268 | 165 exitcode = spawnvpe (P_WAIT, prog_argv[0], (const char **) prog_argv, |
166 (const char **) environ); | |
10544
cb17877a6ccd
Enable use of shell scripts as executables in mingw.
Bruno Haible <bruno@clisp.org>
parents:
10197
diff
changeset
|
167 } |
cb17877a6ccd
Enable use of shell scripts as executables in mingw.
Bruno Haible <bruno@clisp.org>
parents:
10197
diff
changeset
|
168 } |
4936 | 169 if (nulloutfd >= 0) |
170 close (nulloutfd); | |
171 if (nullinfd >= 0) | |
172 close (nullinfd); | |
173 | |
174 /* Restore standard file handles of parent process. */ | |
175 if (null_stderr) | |
176 dup2 (orig_stderr, STDERR_FILENO), close (orig_stderr); | |
177 if (null_stdout) | |
178 dup2 (orig_stdout, STDOUT_FILENO), close (orig_stdout); | |
179 if (null_stdin) | |
180 dup2 (orig_stdin, STDIN_FILENO), close (orig_stdin); | |
181 | |
10197
d079dd7b69bc
Add termsigp argument to execute() and wait_process().
Bruno Haible <bruno@clisp.org>
parents:
9721
diff
changeset
|
182 if (termsigp != NULL) |
d079dd7b69bc
Add termsigp argument to execute() and wait_process().
Bruno Haible <bruno@clisp.org>
parents:
9721
diff
changeset
|
183 *termsigp = 0; |
d079dd7b69bc
Add termsigp argument to execute() and wait_process().
Bruno Haible <bruno@clisp.org>
parents:
9721
diff
changeset
|
184 |
4936 | 185 if (exitcode == -1) |
186 { | |
187 if (exit_on_error || !null_stderr) | |
188 error (exit_on_error ? EXIT_FAILURE : 0, errno, | |
189 _("%s subprocess failed"), progname); | |
190 return 127; | |
191 } | |
192 | |
193 return exitcode; | |
194 | |
195 #else | |
196 | |
197 /* Unix API. */ | |
198 /* Note about 127: Some errors during posix_spawnp() cause the function | |
199 posix_spawnp() to return an error code; some other errors cause the | |
200 subprocess to exit with return code 127. It is implementation | |
201 dependent which error is reported which way. We treat both cases as | |
202 equivalent. */ | |
203 sigset_t blocked_signals; | |
204 posix_spawn_file_actions_t actions; | |
205 bool actions_allocated; | |
206 posix_spawnattr_t attrs; | |
207 bool attrs_allocated; | |
208 int err; | |
209 pid_t child; | |
210 | |
211 if (slave_process) | |
212 { | |
213 sigprocmask (SIG_SETMASK, NULL, &blocked_signals); | |
214 block_fatal_signals (); | |
215 } | |
216 actions_allocated = false; | |
217 attrs_allocated = false; | |
218 if ((err = posix_spawn_file_actions_init (&actions)) != 0 | |
219 || (actions_allocated = true, | |
220 (null_stdin | |
221 && (err = posix_spawn_file_actions_addopen (&actions, | |
222 STDIN_FILENO, | |
223 "/dev/null", O_RDONLY, | |
224 0)) | |
225 != 0) | |
226 || (null_stdout | |
227 && (err = posix_spawn_file_actions_addopen (&actions, | |
228 STDOUT_FILENO, | |
229 "/dev/null", O_RDWR, | |
230 0)) | |
231 != 0) | |
232 || (null_stderr | |
233 && (err = posix_spawn_file_actions_addopen (&actions, | |
234 STDERR_FILENO, | |
235 "/dev/null", O_RDWR, | |
236 0)) | |
237 != 0) | |
238 || (slave_process | |
239 && ((err = posix_spawnattr_init (&attrs)) != 0 | |
240 || (attrs_allocated = true, | |
241 (err = posix_spawnattr_setsigmask (&attrs, | |
242 &blocked_signals)) | |
243 != 0 | |
244 || (err = posix_spawnattr_setflags (&attrs, | |
245 POSIX_SPAWN_SETSIGMASK)) | |
246 != 0))) | |
247 || (err = posix_spawnp (&child, prog_path, &actions, | |
248 attrs_allocated ? &attrs : NULL, prog_argv, | |
249 environ)) | |
250 != 0)) | |
251 { | |
252 if (actions_allocated) | |
253 posix_spawn_file_actions_destroy (&actions); | |
254 if (attrs_allocated) | |
255 posix_spawnattr_destroy (&attrs); | |
256 if (slave_process) | |
257 unblock_fatal_signals (); | |
10197
d079dd7b69bc
Add termsigp argument to execute() and wait_process().
Bruno Haible <bruno@clisp.org>
parents:
9721
diff
changeset
|
258 if (termsigp != NULL) |
d079dd7b69bc
Add termsigp argument to execute() and wait_process().
Bruno Haible <bruno@clisp.org>
parents:
9721
diff
changeset
|
259 *termsigp = 0; |
4936 | 260 if (exit_on_error || !null_stderr) |
261 error (exit_on_error ? EXIT_FAILURE : 0, err, | |
262 _("%s subprocess failed"), progname); | |
263 return 127; | |
264 } | |
265 posix_spawn_file_actions_destroy (&actions); | |
266 if (attrs_allocated) | |
267 posix_spawnattr_destroy (&attrs); | |
268 if (slave_process) | |
269 { | |
270 register_slave_subprocess (child); | |
271 unblock_fatal_signals (); | |
272 } | |
273 | |
6761
14eb5491c867
* lib/wait-process.c, lib/wait-process.h, lib/csharpcomp.c,
Derek R. Price <derek@ximbiot.com>
parents:
6759
diff
changeset
|
274 return wait_subprocess (child, progname, ignore_sigpipe, null_stderr, |
10197
d079dd7b69bc
Add termsigp argument to execute() and wait_process().
Bruno Haible <bruno@clisp.org>
parents:
9721
diff
changeset
|
275 slave_process, exit_on_error, termsigp); |
4936 | 276 |
277 #endif | |
278 } |