2 * Copyright (C) 1996-2000 Michael R. Elkins <me@mutt.org>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
35 int _mutt_system (const char *cmd, int flags)
39 struct sigaction oldtstp;
40 struct sigaction oldcont;
47 /* must ignore SIGINT and SIGQUIT */
49 mutt_block_signals_system ();
51 /* also don't want to be stopped right now */
52 if (flags & M_DETACH_PROCESS) {
54 sigaddset (&set, SIGTSTP);
55 sigprocmask (SIG_BLOCK, &set, NULL);
58 act.sa_handler = SIG_DFL;
59 /* we want to restart the waitpid() below */
61 act.sa_flags = SA_RESTART;
63 sigemptyset (&act.sa_mask);
64 sigaction (SIGTSTP, &act, &oldtstp);
65 sigaction (SIGCONT, &act, &oldcont);
68 if ((thepid = fork ()) == 0) {
71 if (flags & M_DETACH_PROCESS) {
74 /* give up controlling terminal */
80 for (fd = 0; fd < OPEN_MAX; fd++)
82 #elif defined(_POSIX_OPEN_MAX)
83 for (fd = 0; fd < _POSIX_OPEN_MAX; fd++)
91 act.sa_handler = SIG_DFL;
92 sigaction (SIGCHLD, &act, NULL);
103 /* reset signals for the child; not really needed, but... */
104 mutt_unblock_signals_system (0);
105 act.sa_handler = SIG_DFL;
107 sigemptyset (&act.sa_mask);
108 sigaction (SIGTERM, &act, NULL);
109 sigaction (SIGTSTP, &act, NULL);
110 sigaction (SIGCONT, &act, NULL);
112 execl (EXECSHELL, "sh", "-c", cmd, NULL);
113 _exit (127); /* execl error */
115 else if (thepid != -1) {
117 /* wait for the (first) child process to finish */
118 waitpid (thepid, &rc, 0);
120 rc = imap_wait_keepalive (thepid);
124 sigaction (SIGCONT, &oldcont, NULL);
125 sigaction (SIGTSTP, &oldtstp, NULL);
127 /* reset SIGINT, SIGQUIT and SIGCHLD */
128 mutt_unblock_signals_system (1);
129 if (flags & M_DETACH_PROCESS)
130 sigprocmask (SIG_UNBLOCK, &set, NULL);
132 rc = (thepid != -1) ? (WIFEXITED (rc) ? WEXITSTATUS (rc) : -1) : -1;