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 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 General Public License for more details.
17 * You should have received a copy of the GNU 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.
28 #include <libgnome/gnome-i18n.h>
31 #include <sys/types.h>
43 process_fork (const char *path
, char **argv
, gboolean redirect
, int ignfd
, int *infd
, int *outfd
, int *errfd
, GError
**err
)
45 int errnosav
, fds
[6], i
;
48 for (i
= 0; i
< 6; i
++)
51 for (i
= 0; i
< 6; i
+= 2) {
52 if (pipe (fds
+ i
) == -1) {
54 g_set_error (err
, g_quark_from_string ("process"), errno
,
55 _("Failed to create pipe to '%s': %s"),
56 argv
[0], g_strerror (errno
));
58 for (i
= 0; i
< 6; i
++) {
71 fprintf (stderr
, "exec()'ing %s\n", path
);
72 for (i
= 0; argv
[i
]; i
++)
73 fprintf (stderr
, "%s ", argv
[i
]);
74 fprintf (stderr
, "\n");
77 if (!(pid
= fork ())) {
79 int maxfd
, nullfd
= -1;
82 if (!infd
|| !outfd
|| !errfd
)
83 nullfd
= open ("/dev/null", O_WRONLY
);
85 if (dup2 (infd
? fds
[0] : nullfd
, STDIN_FILENO
) == -1)
88 if (dup2 (outfd
? fds
[3] : nullfd
, STDOUT_FILENO
) == -1)
91 if (dup2 (errfd
? fds
[5] : nullfd
, STDERR_FILENO
) == -1)
97 if ((maxfd
= sysconf (_SC_OPEN_MAX
)) > 0) {
100 for (fd
= 3; fd
< maxfd
; fd
++) {
102 fcntl (fd
, F_SETFD
, FD_CLOEXEC
);
108 } else if (pid
== -1) {
109 g_set_error (err
, g_quark_from_string ("process"), errno
,
110 _("Failed to create child process '%s': %s"),
111 argv
[0], g_strerror (errno
));
140 process_wait (pid_t pid
)
142 sigset_t mask
, omask
;
147 sigaddset (&mask
, SIGALRM
);
148 sigprocmask (SIG_BLOCK
, &mask
, &omask
);
151 r
= waitpid (pid
, &status
, 0);
154 sigprocmask (SIG_SETMASK
, &omask
, NULL
);
156 if (r
== (pid_t
) -1 && errno
== EINTR
) {
159 r
= waitpid (pid
, &status
, WNOHANG
);
160 if (r
== (pid_t
) 0) {
163 r
= waitpid (pid
, &status
, WNOHANG
);
167 if (r
!= (pid_t
) -1 && WIFEXITED (status
))
168 return WEXITSTATUS (status
);
175 process_kill (pid_t pid
)
182 r
= waitpid (pid
, &status
, WNOHANG
);
183 if (r
== (pid_t
) 0) {
186 r
= waitpid (pid
, &status
, WNOHANG
);
189 if (r
!= (pid_t
) -1 && WIFEXITED (status
))
190 return WEXITSTATUS (status
);