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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
4936
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
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
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
3 Written by Bruno Haible <haible@clisp.cons.org>, 2001.
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
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
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
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
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
9
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
10 This program is distributed in the hope that it will be useful,
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
13 GNU General Public License for more details.
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
14
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
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
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
17
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
18
7304
1c4ed7637c24 Include <config.h> unconditionally.
Bruno Haible <bruno@clisp.org>
parents: 6761
diff changeset
19 #include <config.h>
4936
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
20
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
21 /* Specification. */
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
22 #include "execute.h"
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
23
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
24 #include <errno.h>
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
25 #include <fcntl.h>
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
26 #include <stdbool.h>
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
27 #include <stdlib.h>
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
28 #include <signal.h>
6751
1b0092424a44 Include <unistd.h> unconditionally.
Bruno Haible <bruno@clisp.org>
parents: 5848
diff changeset
29 #include <unistd.h>
4936
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
30
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
31 #include "error.h"
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
32 #include "fatal-signal.h"
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
33 #include "wait-process.h"
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
34 #include "gettext.h"
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
35
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
36 #define _(str) gettext (str)
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
37
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
38 #if defined _MSC_VER || defined __MINGW32__
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
39
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
40 /* Native Woe32 API. */
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
41 # include <process.h>
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
42 # include "w32spawn.h"
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
43
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
44 #else
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
45
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
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
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
48
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
49 #endif
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
50
7863
cb2590895141 New module 'fchdir'.
Bruno Haible <bruno@clisp.org>
parents: 7304
diff changeset
51 /* The results of open() in this file are not used with fchdir,
cb2590895141 New module 'fchdir'.
Bruno Haible <bruno@clisp.org>
parents: 7304
diff changeset
52 therefore save some unnecessary work in fchdir.c. */
cb2590895141 New module 'fchdir'.
Bruno Haible <bruno@clisp.org>
parents: 7304
diff changeset
53 #undef open
cb2590895141 New module 'fchdir'.
Bruno Haible <bruno@clisp.org>
parents: 7304
diff changeset
54 #undef close
cb2590895141 New module 'fchdir'.
Bruno Haible <bruno@clisp.org>
parents: 7304
diff changeset
55
4936
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
56
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
57 #ifdef EINTR
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
58
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
59 /* EINTR handling for close(), open().
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
60 These functions can return -1/EINTR even though we don't have any
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
61 signal handlers set up, namely when we get interrupted via SIGSTOP. */
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
62
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
63 static inline int
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
64 nonintr_close (int fd)
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
65 {
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
66 int retval;
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
67
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
68 do
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
69 retval = close (fd);
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
70 while (retval < 0 && errno == EINTR);
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
71
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
72 return retval;
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
73 }
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
74 #define close nonintr_close
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
75
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
76 static inline int
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
77 nonintr_open (const char *pathname, int oflag, mode_t mode)
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
78 {
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
79 int retval;
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
80
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
81 do
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
82 retval = open (pathname, oflag, mode);
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
83 while (retval < 0 && errno == EINTR);
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
84
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
85 return retval;
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
86 }
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
87 #undef open /* avoid warning on VMS */
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
88 #define open nonintr_open
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
89
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
90 #endif
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
91
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
92
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
93 /* Execute a command, optionally redirecting any of the three standard file
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
94 descriptors to /dev/null. Return its exit code.
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
95 If it didn't terminate correctly, exit if exit_on_error is true, otherwise
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
96 return 127.
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
97 If slave_process is true, the child process will be terminated when its
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
98 creator receives a catchable fatal signal. */
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
99 int
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
100 execute (const char *progname,
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
101 const char *prog_path, char **prog_argv,
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
102 bool ignore_sigpipe,
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
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
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
106 {
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
107 #if defined _MSC_VER || defined __MINGW32__
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
108
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
109 /* Native Woe32 API. */
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
110 int orig_stdin;
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
111 int orig_stdout;
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
112 int orig_stderr;
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
113 int exitcode;
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
114 int nullinfd;
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
115 int nulloutfd;
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
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
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
118 prog_argv = prepare_spawn (prog_argv);
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
119
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
120 /* Save standard file handles of parent process. */
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
121 if (null_stdin)
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
122 orig_stdin = dup_noinherit (STDIN_FILENO);
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
123 if (null_stdout)
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
124 orig_stdout = dup_noinherit (STDOUT_FILENO);
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
125 if (null_stderr)
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
126 orig_stderr = dup_noinherit (STDERR_FILENO);
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
127 exitcode = -1;
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
128
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
129 /* Create standard file handles of child process. */
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
130 nullinfd = -1;
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
131 nulloutfd = -1;
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
132 if ((!null_stdin
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
133 || ((nullinfd = open ("NUL", O_RDONLY, 0)) >= 0
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
134 && (nullinfd == STDIN_FILENO
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
135 || (dup2 (nullinfd, STDIN_FILENO) >= 0
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
136 && close (nullinfd) >= 0))))
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
137 && (!(null_stdout || null_stderr)
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
138 || ((nulloutfd = open ("NUL", O_RDWR, 0)) >= 0
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
139 && (!null_stdout
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
140 || nulloutfd == STDOUT_FILENO
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
141 || dup2 (nulloutfd, STDOUT_FILENO) >= 0)
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
142 && (!null_stderr
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
143 || nulloutfd == STDERR_FILENO
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
144 || dup2 (nulloutfd, STDERR_FILENO) >= 0)
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
145 && ((null_stdout && nulloutfd == STDOUT_FILENO)
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
146 || (null_stderr && nulloutfd == STDERR_FILENO)
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
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
16ae9ebb84d9 Add casts, to avoid warnings.
Eric Blake <ebb9@byu.net>
parents: 11090
diff changeset
157 exitcode = spawnvpe (P_WAIT, prog_path, (const char **) prog_argv,
16ae9ebb84d9 Add casts, to avoid warnings.
Eric Blake <ebb9@byu.net>
parents: 11090
diff changeset
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
16ae9ebb84d9 Add casts, to avoid warnings.
Eric Blake <ebb9@byu.net>
parents: 11090
diff changeset
165 exitcode = spawnvpe (P_WAIT, prog_argv[0], (const char **) prog_argv,
16ae9ebb84d9 Add casts, to avoid warnings.
Eric Blake <ebb9@byu.net>
parents: 11090
diff changeset
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
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
169 if (nulloutfd >= 0)
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
170 close (nulloutfd);
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
171 if (nullinfd >= 0)
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
172 close (nullinfd);
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
173
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
174 /* Restore standard file handles of parent process. */
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
175 if (null_stderr)
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
176 dup2 (orig_stderr, STDERR_FILENO), close (orig_stderr);
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
177 if (null_stdout)
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
178 dup2 (orig_stdout, STDOUT_FILENO), close (orig_stdout);
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
179 if (null_stdin)
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
180 dup2 (orig_stdin, STDIN_FILENO), close (orig_stdin);
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
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
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
185 if (exitcode == -1)
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
186 {
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
187 if (exit_on_error || !null_stderr)
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
188 error (exit_on_error ? EXIT_FAILURE : 0, errno,
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
189 _("%s subprocess failed"), progname);
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
190 return 127;
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
191 }
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
192
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
193 return exitcode;
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
194
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
195 #else
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
196
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
197 /* Unix API. */
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
198 /* Note about 127: Some errors during posix_spawnp() cause the function
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
199 posix_spawnp() to return an error code; some other errors cause the
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
200 subprocess to exit with return code 127. It is implementation
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
201 dependent which error is reported which way. We treat both cases as
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
202 equivalent. */
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
203 sigset_t blocked_signals;
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
204 posix_spawn_file_actions_t actions;
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
205 bool actions_allocated;
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
206 posix_spawnattr_t attrs;
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
207 bool attrs_allocated;
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
208 int err;
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
209 pid_t child;
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
210
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
211 if (slave_process)
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
212 {
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
213 sigprocmask (SIG_SETMASK, NULL, &blocked_signals);
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
214 block_fatal_signals ();
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
215 }
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
216 actions_allocated = false;
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
217 attrs_allocated = false;
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
218 if ((err = posix_spawn_file_actions_init (&actions)) != 0
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
219 || (actions_allocated = true,
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
220 (null_stdin
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
221 && (err = posix_spawn_file_actions_addopen (&actions,
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
222 STDIN_FILENO,
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
223 "/dev/null", O_RDONLY,
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
224 0))
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
225 != 0)
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
226 || (null_stdout
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
227 && (err = posix_spawn_file_actions_addopen (&actions,
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
228 STDOUT_FILENO,
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
229 "/dev/null", O_RDWR,
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
230 0))
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
231 != 0)
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
232 || (null_stderr
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
233 && (err = posix_spawn_file_actions_addopen (&actions,
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
234 STDERR_FILENO,
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
235 "/dev/null", O_RDWR,
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
236 0))
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
237 != 0)
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
238 || (slave_process
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
239 && ((err = posix_spawnattr_init (&attrs)) != 0
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
240 || (attrs_allocated = true,
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
241 (err = posix_spawnattr_setsigmask (&attrs,
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
242 &blocked_signals))
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
243 != 0
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
244 || (err = posix_spawnattr_setflags (&attrs,
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
245 POSIX_SPAWN_SETSIGMASK))
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
246 != 0)))
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
247 || (err = posix_spawnp (&child, prog_path, &actions,
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
248 attrs_allocated ? &attrs : NULL, prog_argv,
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
249 environ))
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
250 != 0))
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
251 {
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
252 if (actions_allocated)
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
253 posix_spawn_file_actions_destroy (&actions);
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
254 if (attrs_allocated)
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
255 posix_spawnattr_destroy (&attrs);
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
256 if (slave_process)
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
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
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
260 if (exit_on_error || !null_stderr)
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
261 error (exit_on_error ? EXIT_FAILURE : 0, err,
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
262 _("%s subprocess failed"), progname);
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
263 return 127;
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
264 }
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
265 posix_spawn_file_actions_destroy (&actions);
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
266 if (attrs_allocated)
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
267 posix_spawnattr_destroy (&attrs);
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
268 if (slave_process)
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
269 {
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
270 register_slave_subprocess (child);
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
271 unblock_fatal_signals ();
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
272 }
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
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
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
276
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
277 #endif
0fb731aa9b43 New module 'execute'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
278 }