1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
3 * Authors: Jeffrey Stedfast <fejj@ximian.com>
5 * Copyright 2003 Ximian, Inc. (www.ximian.com)
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU Lesser General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
32 #include "camel-process.h"
36 camel_process_fork (const char *path, char **argv, int *infd, int *outfd, int *errfd, CamelException *ex)
38 int errnosav, fd[6], i;
41 for (i = 0; i < 6; i++)
44 for (i = 0; i < 6; i += 2) {
45 if (pipe (fd + i) == -1) {
47 camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
48 _("Failed to create pipe to '%s': %s"),
49 argv[0], strerror (errno));
51 for (i = 0; i < 6; i++) {
63 if (!(pid = fork ())) {
65 int maxfd, nullfd = -1;
68 nullfd = open ("/dev/null", O_WRONLY);
70 if (dup2 (fd[0], STDIN_FILENO) == -1)
73 if (dup2 (outfd ? fd[3] : nullfd, STDOUT_FILENO) == -1)
76 if (dup2 (errfd ? fd[5] : nullfd, STDERR_FILENO) == -1)
81 if ((maxfd = sysconf (_SC_OPEN_MAX)) > 0) {
82 for (i = 3; i < maxfd; i++)
83 fcntl (i, F_SETFD, FD_CLOEXEC);
88 } else if (pid == -1) {
89 camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
90 _("Failed to create child process '%s': %s"),
91 argv[0], strerror (errno));
92 for (i = 0; i < 6; i++)
122 camel_process_wait (pid_t pid)
124 sigset_t mask, omask;
129 sigaddset (&mask, SIGALRM);
130 sigprocmask (SIG_BLOCK, &mask, &omask);
133 r = waitpid (pid, &status, 0);
136 sigprocmask (SIG_SETMASK, &omask, NULL);
138 if (r == (pid_t) -1 && errno == EINTR) {
141 r = waitpid (pid, &status, WNOHANG);
142 if (r == (pid_t) 0) {
145 r = waitpid (pid, &status, WNOHANG);
149 if (r != (pid_t) -1 && WIFEXITED (status))
150 return WEXITSTATUS (status);