getprogname: Work around program name truncation when possible.
[gnulib.git] / lib / spawn-pipe.c
blobec9bd9dc0ae0f771f9b10ddec20a5bd5ebc138bf
1 /* Creation of subprocesses, communicating via pipes.
2 Copyright (C) 2001-2004, 2006-2018 Free Software Foundation, Inc.
3 Written by Bruno Haible <haible@clisp.cons.org>, 2001.
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3 of the License, or
8 (at your option) any later version.
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.
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <https://www.gnu.org/licenses/>. */
19 /* Tell clang not to warn about the 'child' variable, below. */
20 #if defined __clang__
21 # pragma clang diagnostic ignored "-Wconditional-uninitialized"
22 #endif
24 #include <config.h>
26 /* Specification. */
27 #include "spawn-pipe.h"
29 #include <errno.h>
30 #include <fcntl.h>
31 #include <stdlib.h>
32 #include <signal.h>
33 #include <unistd.h>
35 #include "error.h"
36 #include "fatal-signal.h"
37 #include "unistd-safer.h"
38 #include "wait-process.h"
39 #include "gettext.h"
41 #define _(str) gettext (str)
43 #if (defined _WIN32 && ! defined __CYGWIN__) || defined __KLIBC__
45 /* Native Windows API. */
46 # include <process.h>
47 # include "w32spawn.h"
49 #else
51 /* Unix API. */
52 # include <spawn.h>
54 #endif
57 #ifdef EINTR
59 /* EINTR handling for close().
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. */
63 static int
64 nonintr_close (int fd)
66 int retval;
69 retval = close (fd);
70 while (retval < 0 && errno == EINTR);
72 return retval;
74 #undef close /* avoid warning related to gnulib module unistd */
75 #define close nonintr_close
77 #if defined _WIN32 && ! defined __CYGWIN__
78 static int
79 nonintr_open (const char *pathname, int oflag, mode_t mode)
81 int retval;
84 retval = open (pathname, oflag, mode);
85 while (retval < 0 && errno == EINTR);
87 return retval;
89 # undef open /* avoid warning on VMS */
90 # define open nonintr_open
91 #endif
93 #endif
96 /* Open a pipe connected to a child process.
98 * write system read
99 * parent -> fd[1] -> STDIN_FILENO -> child if pipe_stdin
100 * parent <- fd[0] <- STDOUT_FILENO <- child if pipe_stdout
101 * read system write
103 * At least one of pipe_stdin, pipe_stdout must be true.
104 * pipe_stdin and prog_stdin together determine the child's standard input.
105 * pipe_stdout and prog_stdout together determine the child's standard output.
106 * If pipe_stdin is true, prog_stdin is ignored.
107 * If pipe_stdout is true, prog_stdout is ignored.
109 static pid_t
110 create_pipe (const char *progname,
111 const char *prog_path, char **prog_argv,
112 bool pipe_stdin, bool pipe_stdout,
113 const char *prog_stdin, const char *prog_stdout,
114 bool null_stderr,
115 bool slave_process, bool exit_on_error,
116 int fd[2])
118 #if (defined _WIN32 && ! defined __CYGWIN__) || defined __KLIBC__
120 /* Native Windows API.
121 This uses _pipe(), dup2(), and spawnv(). It could also be implemented
122 using the low-level functions CreatePipe(), DuplicateHandle(),
123 CreateProcess() and _open_osfhandle(); see the GNU make and GNU clisp
124 and cvs source code. */
125 int ifd[2];
126 int ofd[2];
127 int orig_stdin;
128 int orig_stdout;
129 int orig_stderr;
130 int child;
131 int nulloutfd;
132 int stdinfd;
133 int stdoutfd;
134 int saved_errno;
136 /* FIXME: Need to free memory allocated by prepare_spawn. */
137 prog_argv = prepare_spawn (prog_argv);
139 if (pipe_stdout)
140 if (pipe2_safer (ifd, O_BINARY | O_CLOEXEC) < 0)
141 error (EXIT_FAILURE, errno, _("cannot create pipe"));
142 if (pipe_stdin)
143 if (pipe2_safer (ofd, O_BINARY | O_CLOEXEC) < 0)
144 error (EXIT_FAILURE, errno, _("cannot create pipe"));
145 /* Data flow diagram:
147 * write system read
148 * parent -> ofd[1] -> ofd[0] -> child if pipe_stdin
149 * parent <- ifd[0] <- ifd[1] <- child if pipe_stdout
150 * read system write
154 /* Save standard file handles of parent process. */
155 if (pipe_stdin || prog_stdin != NULL)
156 orig_stdin = dup_safer_noinherit (STDIN_FILENO);
157 if (pipe_stdout || prog_stdout != NULL)
158 orig_stdout = dup_safer_noinherit (STDOUT_FILENO);
159 if (null_stderr)
160 orig_stderr = dup_safer_noinherit (STDERR_FILENO);
161 child = -1;
163 /* Create standard file handles of child process. */
164 nulloutfd = -1;
165 stdinfd = -1;
166 stdoutfd = -1;
167 if ((!pipe_stdin || dup2 (ofd[0], STDIN_FILENO) >= 0)
168 && (!pipe_stdout || dup2 (ifd[1], STDOUT_FILENO) >= 0)
169 && (!null_stderr
170 || ((nulloutfd = open ("NUL", O_RDWR, 0)) >= 0
171 && (nulloutfd == STDERR_FILENO
172 || (dup2 (nulloutfd, STDERR_FILENO) >= 0
173 && close (nulloutfd) >= 0))))
174 && (pipe_stdin
175 || prog_stdin == NULL
176 || ((stdinfd = open (prog_stdin, O_RDONLY, 0)) >= 0
177 && (stdinfd == STDIN_FILENO
178 || (dup2 (stdinfd, STDIN_FILENO) >= 0
179 && close (stdinfd) >= 0))))
180 && (pipe_stdout
181 || prog_stdout == NULL
182 || ((stdoutfd = open (prog_stdout, O_WRONLY, 0)) >= 0
183 && (stdoutfd == STDOUT_FILENO
184 || (dup2 (stdoutfd, STDOUT_FILENO) >= 0
185 && close (stdoutfd) >= 0)))))
186 /* The child process doesn't inherit ifd[0], ifd[1], ofd[0], ofd[1],
187 but it inherits all open()ed or dup2()ed file handles (which is what
188 we want in the case of STD*_FILENO). */
189 /* Use spawnvpe and pass the environment explicitly. This is needed if
190 the program has modified the environment using putenv() or [un]setenv().
191 On Windows, programs have two environments, one in the "environment
192 block" of the process and managed through SetEnvironmentVariable(), and
193 one inside the process, in the location retrieved by the 'environ'
194 macro. When using spawnvp() without 'e', the child process inherits a
195 copy of the environment block - ignoring the effects of putenv() and
196 [un]setenv(). */
198 child = spawnvpe (P_NOWAIT, prog_path, (const char **) prog_argv,
199 (const char **) environ);
200 if (child < 0 && errno == ENOEXEC)
202 /* prog is not a native executable. Try to execute it as a
203 shell script. Note that prepare_spawn() has already prepended
204 a hidden element "sh.exe" to prog_argv. */
205 --prog_argv;
206 child = spawnvpe (P_NOWAIT, prog_argv[0], (const char **) prog_argv,
207 (const char **) environ);
210 if (child == -1)
211 saved_errno = errno;
212 if (stdinfd >= 0)
213 close (stdinfd);
214 if (stdoutfd >= 0)
215 close (stdoutfd);
216 if (nulloutfd >= 0)
217 close (nulloutfd);
219 /* Restore standard file handles of parent process. */
220 if (null_stderr)
221 undup_safer_noinherit (orig_stderr, STDERR_FILENO);
222 if (pipe_stdout || prog_stdout != NULL)
223 undup_safer_noinherit (orig_stdout, STDOUT_FILENO);
224 if (pipe_stdin || prog_stdin != NULL)
225 undup_safer_noinherit (orig_stdin, STDIN_FILENO);
227 if (pipe_stdin)
228 close (ofd[0]);
229 if (pipe_stdout)
230 close (ifd[1]);
231 if (child == -1)
233 if (exit_on_error || !null_stderr)
234 error (exit_on_error ? EXIT_FAILURE : 0, saved_errno,
235 _("%s subprocess failed"), progname);
236 if (pipe_stdout)
237 close (ifd[0]);
238 if (pipe_stdin)
239 close (ofd[1]);
240 errno = saved_errno;
241 return -1;
244 if (pipe_stdout)
245 fd[0] = ifd[0];
246 if (pipe_stdin)
247 fd[1] = ofd[1];
248 return child;
250 #else
252 /* Unix API. */
253 int ifd[2];
254 int ofd[2];
255 sigset_t blocked_signals;
256 posix_spawn_file_actions_t actions;
257 bool actions_allocated;
258 posix_spawnattr_t attrs;
259 bool attrs_allocated;
260 int err;
261 pid_t child;
263 if (pipe_stdout)
264 if (pipe_safer (ifd) < 0)
265 error (EXIT_FAILURE, errno, _("cannot create pipe"));
266 if (pipe_stdin)
267 if (pipe_safer (ofd) < 0)
268 error (EXIT_FAILURE, errno, _("cannot create pipe"));
269 /* Data flow diagram:
271 * write system read
272 * parent -> ofd[1] -> ofd[0] -> child if pipe_stdin
273 * parent <- ifd[0] <- ifd[1] <- child if pipe_stdout
274 * read system write
278 if (slave_process)
280 sigprocmask (SIG_SETMASK, NULL, &blocked_signals);
281 block_fatal_signals ();
283 actions_allocated = false;
284 attrs_allocated = false;
285 if ((err = posix_spawn_file_actions_init (&actions)) != 0
286 || (actions_allocated = true,
287 (pipe_stdin
288 && (err = posix_spawn_file_actions_adddup2 (&actions,
289 ofd[0], STDIN_FILENO))
290 != 0)
291 || (pipe_stdout
292 && (err = posix_spawn_file_actions_adddup2 (&actions,
293 ifd[1], STDOUT_FILENO))
294 != 0)
295 || (pipe_stdin
296 && (err = posix_spawn_file_actions_addclose (&actions, ofd[0]))
297 != 0)
298 || (pipe_stdout
299 && (err = posix_spawn_file_actions_addclose (&actions, ifd[1]))
300 != 0)
301 || (pipe_stdin
302 && (err = posix_spawn_file_actions_addclose (&actions, ofd[1]))
303 != 0)
304 || (pipe_stdout
305 && (err = posix_spawn_file_actions_addclose (&actions, ifd[0]))
306 != 0)
307 || (null_stderr
308 && (err = posix_spawn_file_actions_addopen (&actions,
309 STDERR_FILENO,
310 "/dev/null", O_RDWR,
312 != 0)
313 || (!pipe_stdin
314 && prog_stdin != NULL
315 && (err = posix_spawn_file_actions_addopen (&actions,
316 STDIN_FILENO,
317 prog_stdin, O_RDONLY,
319 != 0)
320 || (!pipe_stdout
321 && prog_stdout != NULL
322 && (err = posix_spawn_file_actions_addopen (&actions,
323 STDOUT_FILENO,
324 prog_stdout, O_WRONLY,
326 != 0)
327 || (slave_process
328 && ((err = posix_spawnattr_init (&attrs)) != 0
329 || (attrs_allocated = true,
330 (err = posix_spawnattr_setsigmask (&attrs,
331 &blocked_signals))
332 != 0
333 || (err = posix_spawnattr_setflags (&attrs,
334 POSIX_SPAWN_SETSIGMASK))
335 != 0)))
336 || (err = posix_spawnp (&child, prog_path, &actions,
337 attrs_allocated ? &attrs : NULL, prog_argv,
338 environ))
339 != 0))
341 if (actions_allocated)
342 posix_spawn_file_actions_destroy (&actions);
343 if (attrs_allocated)
344 posix_spawnattr_destroy (&attrs);
345 if (slave_process)
346 unblock_fatal_signals ();
347 if (exit_on_error || !null_stderr)
348 error (exit_on_error ? EXIT_FAILURE : 0, err,
349 _("%s subprocess failed"), progname);
350 if (pipe_stdout)
352 close (ifd[0]);
353 close (ifd[1]);
355 if (pipe_stdin)
357 close (ofd[0]);
358 close (ofd[1]);
360 errno = err;
361 return -1;
363 posix_spawn_file_actions_destroy (&actions);
364 if (attrs_allocated)
365 posix_spawnattr_destroy (&attrs);
366 if (slave_process)
368 register_slave_subprocess (child);
369 unblock_fatal_signals ();
371 if (pipe_stdin)
372 close (ofd[0]);
373 if (pipe_stdout)
374 close (ifd[1]);
376 if (pipe_stdout)
377 fd[0] = ifd[0];
378 if (pipe_stdin)
379 fd[1] = ofd[1];
380 return child;
382 #endif
385 /* Open a bidirectional pipe.
387 * write system read
388 * parent -> fd[1] -> STDIN_FILENO -> child
389 * parent <- fd[0] <- STDOUT_FILENO <- child
390 * read system write
393 pid_t
394 create_pipe_bidi (const char *progname,
395 const char *prog_path, char **prog_argv,
396 bool null_stderr,
397 bool slave_process, bool exit_on_error,
398 int fd[2])
400 pid_t result = create_pipe (progname, prog_path, prog_argv,
401 true, true, NULL, NULL,
402 null_stderr, slave_process, exit_on_error,
403 fd);
404 return result;
407 /* Open a pipe for input from a child process.
408 * The child's stdin comes from a file.
410 * read system write
411 * parent <- fd[0] <- STDOUT_FILENO <- child
414 pid_t
415 create_pipe_in (const char *progname,
416 const char *prog_path, char **prog_argv,
417 const char *prog_stdin, bool null_stderr,
418 bool slave_process, bool exit_on_error,
419 int fd[1])
421 int iofd[2];
422 pid_t result = create_pipe (progname, prog_path, prog_argv,
423 false, true, prog_stdin, NULL,
424 null_stderr, slave_process, exit_on_error,
425 iofd);
426 if (result != -1)
427 fd[0] = iofd[0];
428 return result;
431 /* Open a pipe for output to a child process.
432 * The child's stdout goes to a file.
434 * write system read
435 * parent -> fd[0] -> STDIN_FILENO -> child
438 pid_t
439 create_pipe_out (const char *progname,
440 const char *prog_path, char **prog_argv,
441 const char *prog_stdout, bool null_stderr,
442 bool slave_process, bool exit_on_error,
443 int fd[1])
445 int iofd[2];
446 pid_t result = create_pipe (progname, prog_path, prog_argv,
447 true, false, NULL, prog_stdout,
448 null_stderr, slave_process, exit_on_error,
449 iofd);
450 if (result != -1)
451 fd[0] = iofd[1];
452 return result;