1 /* exechelp.c - Fork and exec helpers for POSIX
2 * Copyright (C) 2004, 2007, 2008, 2009,
3 * 2010 Free Software Foundation, Inc.
5 * This file is part of GnuPG.
7 * This file is free software; you can redistribute it and/or modify
8 * it under the terms of either
10 * - the GNU Lesser General Public License as published by the Free
11 * Software Foundation; either version 3 of the License, or (at
12 * your option) any later version.
16 * - the GNU General Public License as published by the Free
17 * Software Foundation; either version 2 of the License, or (at
18 * your option) any later version.
20 * or both in parallel, as here.
22 * This file is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
27 * You should have received a copy of the GNU General Public License
28 * along with this program; if not, see <https://www.gnu.org/licenses/>.
33 #if defined(HAVE_W32_SYSTEM) || defined (HAVE_W32CE_SYSTEM)
34 #error This code is only used on POSIX
49 #ifdef WITHOUT_NPTH /* Give the Makefile a chance to build without Pth. */
61 #include <sys/resource.h>
62 #endif /*HAVE_GETRLIMIT*/
65 # include <sys/stat.h>
69 # include <sys/types.h>
80 static inline gpg_error_t
81 my_error_from_syserror (void)
83 return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
86 static inline gpg_error_t
87 my_error (int errcode)
89 return gpg_err_make (default_errsource, errcode);
93 /* Return the maximum number of currently allowed open file
94 descriptors. Only useful on POSIX systems but returns a value on
100 #ifdef HAVE_GETRLIMIT
103 /* Under Linux we can figure out the highest used file descriptor by
104 * reading /proc/PID/fd. This is in the common cases much fast than
105 * for example doing 4096 close calls where almost all of them will
106 * fail. On a system with a limit of 4096 files and only 8 files
107 * open with the highest number being 10, we speedup close_all_fds
108 * from 125ms to 0.4ms including readdir.
110 * Another option would be to close the file descriptors as returned
111 * from reading that directory - however then we need to snapshot
112 * that list before starting to close them. */
116 struct dirent *dir_entry;
120 dir = opendir ("/proc/self/fd");
123 while ((dir_entry = readdir (dir)))
125 s = dir_entry->d_name;
126 if ( *s < '0' || *s > '9')
137 #endif /* __linux__ */
140 # ifdef RLIMIT_NOFILE
141 if (!getrlimit (RLIMIT_NOFILE, &rl))
142 max_fds = rl.rlim_max;
146 if (max_fds == -1 && !getrlimit (RLIMIT_OFILE, &rl))
147 max_fds = rl.rlim_max;
150 #endif /*HAVE_GETRLIMIT*/
155 long int scres = sysconf (_SC_OPEN_MAX);
161 #ifdef _POSIX_OPEN_MAX
163 max_fds = _POSIX_OPEN_MAX;
172 max_fds = 256; /* Arbitrary limit. */
174 /* AIX returns INT32_MAX instead of a proper value. We assume that
175 this is always an error and use an arbitrary limit. */
177 if (max_fds == INT32_MAX)
185 /* Close all file descriptors starting with descriptor FIRST. If
186 EXCEPT is not NULL, it is expected to be a list of file descriptors
187 which shall not be closed. This list shall be sorted in ascending
188 order with the end marked by -1. */
190 close_all_fds (int first, int *except)
192 int max_fd = get_max_fds ();
193 int fd, i, except_start;
198 for (fd=first; fd < max_fd; fd++)
200 for (i=except_start; except[i] != -1; i++)
204 /* If we found the descriptor in the exception list
205 we can start the next compare run at the next
206 index because the exception list is ordered. */
207 except_start = i + 1;
217 for (fd=first; fd < max_fd; fd++)
221 gpg_err_set_errno (0);
225 /* Returns an array with all currently open file descriptors. The end
226 of the array is marked by -1. The caller needs to release this
227 array using the *standard free* and not with xfree. This allow the
228 use of this function right at startup even before libgcrypt has
229 been initialized. Returns NULL on error and sets ERRNO
232 get_all_open_fds (void)
238 array = calloc (1, sizeof *array);
244 max_fd = get_max_fds ();
245 narray = 32; /* If you change this change also t-exechelp.c. */
246 array = calloc (narray, sizeof *array);
250 /* Note: The list we return is ordered. */
251 for (idx=0, fd=0; fd < max_fd; fd++)
252 if (!(fstat (fd, &statbuf) == -1 && errno == EBADF))
258 narray += (narray < 256)? 32:256;
259 tmp = realloc (array, narray * sizeof *array);
275 /* The exec core used right after the fork. This will never return. */
277 do_exec (const char *pgmname, const char *argv[],
278 int fd_in, int fd_out, int fd_err,
279 int *except, void (*preexec)(void) )
289 /* Create the command line argument array. */
294 arg_list = xcalloc (i+2, sizeof *arg_list);
295 arg_list[0] = strrchr (pgmname, '/');
299 arg_list[0] = xstrdup (pgmname);
301 for (i=0,j=1; argv[i]; i++, j++)
302 arg_list[j] = (char*)argv[i];
304 /* Assign /dev/null to unused FDs. */
305 for (i=0; i <= 2; i++)
309 fds[i] = open ("/dev/null", i? O_WRONLY : O_RDONLY);
311 log_fatal ("failed to open '%s': %s\n",
312 "/dev/null", strerror (errno));
316 /* Connect the standard files. */
317 for (i=0; i <= 2; i++)
319 if (fds[i] != i && dup2 (fds[i], i) == -1)
320 log_fatal ("dup2 std%s failed: %s\n",
321 i==0?"in":i==1?"out":"err", strerror (errno));
324 /* Close all other files. */
325 close_all_fds (3, except);
329 execv (pgmname, arg_list);
330 /* No way to print anything, as we have closed all streams. */
336 do_create_pipe (int filedes[2])
340 if (pipe (filedes) == -1)
342 err = my_error_from_syserror ();
343 filedes[0] = filedes[1] = -1;
351 create_pipe_and_estream (int filedes[2], estream_t *r_fp,
352 int outbound, int nonblock)
356 if (pipe (filedes) == -1)
358 err = my_error_from_syserror ();
359 log_error (_("error creating a pipe: %s\n"), gpg_strerror (err));
360 filedes[0] = filedes[1] = -1;
366 *r_fp = es_fdopen (filedes[0], nonblock? "r,nonblock" : "r");
368 *r_fp = es_fdopen (filedes[1], nonblock? "w,nonblock" : "w");
371 err = my_error_from_syserror ();
372 log_error (_("error creating a stream for a pipe: %s\n"),
376 filedes[0] = filedes[1] = -1;
383 /* Portable function to create a pipe. Under Windows the write end is
384 inheritable. If R_FP is not NULL, an estream is created for the
385 read end and stored at R_FP. */
387 gnupg_create_inbound_pipe (int filedes[2], estream_t *r_fp, int nonblock)
390 return create_pipe_and_estream (filedes, r_fp, 0, nonblock);
392 return do_create_pipe (filedes);
396 /* Portable function to create a pipe. Under Windows the read end is
397 inheritable. If R_FP is not NULL, an estream is created for the
398 write end and stored at R_FP. */
400 gnupg_create_outbound_pipe (int filedes[2], estream_t *r_fp, int nonblock)
403 return create_pipe_and_estream (filedes, r_fp, 1, nonblock);
405 return do_create_pipe (filedes);
409 /* Portable function to create a pipe. Under Windows both ends are
412 gnupg_create_pipe (int filedes[2])
414 return do_create_pipe (filedes);
418 /* Fork and exec the PGMNAME, see exechelp.h for details. */
420 gnupg_spawn_process (const char *pgmname, const char *argv[],
421 int *except, void (*preexec)(void), unsigned int flags,
428 int inpipe[2] = {-1, -1};
429 int outpipe[2] = {-1, -1};
430 int errpipe[2] = {-1, -1};
431 estream_t infp = NULL;
432 estream_t outfp = NULL;
433 estream_t errfp = NULL;
434 int nonblock = !!(flags & GNUPG_SPAWN_NONBLOCK);
442 *pid = (pid_t)(-1); /* Always required. */
446 err = create_pipe_and_estream (inpipe, &infp, 1, nonblock);
453 err = create_pipe_and_estream (outpipe, &outfp, 0, nonblock);
458 else if (inpipe[1] != -1)
469 err = create_pipe_and_estream (errpipe, &errfp, 0, nonblock);
474 else if (inpipe[1] != -1)
481 else if (outpipe[0] != -1)
483 if (outpipe[1] != -1)
492 if (*pid == (pid_t)(-1))
494 err = my_error_from_syserror ();
495 log_error (_("error forking process: %s\n"), gpg_strerror (err));
499 else if (inpipe[1] != -1)
506 else if (outpipe[0] != -1)
508 if (outpipe[1] != -1)
513 else if (errpipe[0] != -1)
515 if (errpipe[1] != -1)
522 /* This is the child. */
523 gcry_control (GCRYCTL_TERM_SECMEM);
527 do_exec (pgmname, argv, inpipe[0], outpipe[1], errpipe[1],
532 /* This is the parent. */
535 if (outpipe[1] != -1)
537 if (errpipe[1] != -1)
552 /* Simplified version of gnupg_spawn_process. This function forks and
553 then execs PGMNAME, while connecting INFD to stdin, OUTFD to stdout
554 and ERRFD to stderr (any of them may be -1 to connect them to
555 /dev/null). The arguments for the process are expected in the NULL
556 terminated array ARGV. The program name itself should not be
557 included there. Calling gnupg_wait_process is required.
559 Returns 0 on success or an error code. */
561 gnupg_spawn_process_fd (const char *pgmname, const char *argv[],
562 int infd, int outfd, int errfd, pid_t *pid)
567 if (*pid == (pid_t)(-1))
569 err = my_error_from_syserror ();
570 log_error (_("error forking process: %s\n"), strerror (errno));
576 gcry_control (GCRYCTL_TERM_SECMEM);
578 do_exec (pgmname, argv, infd, outfd, errfd, NULL, NULL);
588 /* Waiting for child processes.
590 waitpid(2) may return information about terminated children that we
591 did not yet request, and there is no portable way to wait for a
592 specific set of children.
594 As a workaround, we store the results of children for later use.
596 XXX: This assumes that PIDs are not reused too quickly. */
598 struct terminated_child
602 struct terminated_child *next;
605 struct terminated_child *terminated_children;
609 store_result (pid_t pid, int exitcode)
611 struct terminated_child *c;
613 c = xtrymalloc (sizeof *c);
615 return gpg_err_code_from_syserror ();
618 c->exitcode = exitcode;
619 c->next = terminated_children;
620 terminated_children = c;
627 get_result (pid_t pid, int *r_exitcode)
629 struct terminated_child *c, **prevp;
631 for (prevp = &terminated_children, c = terminated_children;
633 prevp = &c->next, c = c->next)
637 *r_exitcode = c->exitcode;
646 /* See exechelp.h for a description. */
648 gnupg_wait_process (const char *pgmname, pid_t pid, int hang, int *r_exitcode)
656 if (pid == (pid_t)(-1))
657 return gpg_error (GPG_ERR_INV_VALUE);
660 i = npth_waitpid (pid, &status, hang? 0:WNOHANG);
662 while ((i=waitpid (pid, &status, hang? 0:WNOHANG)) == (pid_t)(-1)
666 if (i == (pid_t)(-1))
668 ec = gpg_err_code_from_errno (errno);
669 log_error (_("waiting for process %d to terminate failed: %s\n"),
670 (int)pid, strerror (errno));
674 ec = GPG_ERR_TIMEOUT; /* Still running. */
676 else if (WIFEXITED (status) && WEXITSTATUS (status) == 127)
678 log_error (_("error running '%s': probably not installed\n"), pgmname);
679 ec = GPG_ERR_CONFIGURATION;
681 else if (WIFEXITED (status) && WEXITSTATUS (status))
684 log_error (_("error running '%s': exit status %d\n"), pgmname,
685 WEXITSTATUS (status));
687 *r_exitcode = WEXITSTATUS (status);
688 ec = GPG_ERR_GENERAL;
690 else if (!WIFEXITED (status))
692 log_error (_("error running '%s': terminated\n"), pgmname);
693 ec = GPG_ERR_GENERAL;
702 return gpg_err_make (GPG_ERR_SOURCE_DEFAULT, ec);
705 /* See exechelp.h for a description. */
707 gnupg_wait_processes (const char **pgmnames, pid_t *pids, size_t count,
708 int hang, int *r_exitcodes)
710 gpg_err_code_t ec = 0;
714 if (r_exitcodes == NULL)
716 dummy = r_exitcodes = xtrymalloc (sizeof *r_exitcodes * count);
718 return gpg_err_code_from_syserror ();
721 for (i = 0, left = count; i < count; i++)
725 if (pids[i] == (pid_t)(-1))
726 return my_error (GPG_ERR_INV_VALUE);
728 /* See if there was a previously stored result for this pid. */
729 if (get_result (pids[i], &status))
732 r_exitcodes[i] = status;
741 pid = npth_waitpid (-1, &status, hang ? 0 : WNOHANG);
743 while ((pid = waitpid (-1, &status, hang ? 0 : WNOHANG)) == (pid_t)(-1)
747 if (pid == (pid_t)(-1))
749 ec = gpg_err_code_from_errno (errno);
750 log_error (_("waiting for processes to terminate failed: %s\n"),
756 ec = GPG_ERR_TIMEOUT; /* Still running. */
761 for (i = 0; i < count; i++)
767 /* No match, store this result. */
768 ec = store_result (pid, status);
774 /* Process PIDS[i] died. */
775 if (r_exitcodes[i] != (pid_t) -1)
777 log_error ("PID %d was reused", pid);
778 ec = GPG_ERR_GENERAL;
783 r_exitcodes[i] = status;
788 for (i = 0; i < count; i++)
790 if (WIFEXITED (r_exitcodes[i]) && WEXITSTATUS (r_exitcodes[i]) == 127)
792 log_error (_("error running '%s': probably not installed\n"),
794 ec = GPG_ERR_CONFIGURATION;
796 else if (WIFEXITED (r_exitcodes[i]) && WEXITSTATUS (r_exitcodes[i]))
799 log_error (_("error running '%s': exit status %d\n"),
800 pgmnames[i], WEXITSTATUS (r_exitcodes[i]));
802 r_exitcodes[i] = WEXITSTATUS (r_exitcodes[i]);
803 ec = GPG_ERR_GENERAL;
805 else if (!WIFEXITED (r_exitcodes[i]))
807 log_error (_("error running '%s': terminated\n"), pgmnames[i]);
808 ec = GPG_ERR_GENERAL;
813 return gpg_err_make (GPG_ERR_SOURCE_DEFAULT, ec);
819 gnupg_release_process (pid_t pid)
825 /* Spawn a new process and immediately detach from it. The name of
826 the program to exec is PGMNAME and its arguments are in ARGV (the
827 programname is automatically passed as first argument).
828 Environment strings in ENVP are set. An error is returned if
829 pgmname is not executable; to make this work it is necessary to
830 provide an absolute file name. All standard file descriptors are
831 connected to /dev/null. */
833 gnupg_spawn_process_detached (const char *pgmname, const char *argv[],
839 if (getuid() != geteuid())
840 return my_error (GPG_ERR_BUG);
842 if (access (pgmname, X_OK))
843 return my_error_from_syserror ();
846 if (pid == (pid_t)(-1))
848 log_error (_("error forking process: %s\n"), strerror (errno));
849 return my_error_from_syserror ();
855 gcry_control (GCRYCTL_TERM_SECMEM);
856 if (setsid() == -1 || chdir ("/"))
859 pid2 = fork (); /* Double fork to let init take over the new child. */
860 if (pid2 == (pid_t)(-1))
863 _exit (0); /* Let the parent exit immediately. */
866 for (i=0; envp[i]; i++)
867 putenv (xstrdup (envp[i]));
869 do_exec (pgmname, argv, -1, -1, -1, NULL, NULL);
874 if (waitpid (pid, NULL, 0) == -1)
875 log_error ("waitpid failed in gnupg_spawn_process_detached: %s",
882 /* Kill a process; that is send an appropriate signal to the process.
883 gnupg_wait_process must be called to actually remove the process
884 from the system. An invalid PID is ignored. */
886 gnupg_kill_process (pid_t pid)
888 if (pid != (pid_t)(-1))