2 * Copyright notice from original mutt:
3 * Copyright (C) 1996-2000 Michael R. Elkins <me@mutt.org>
5 * This file is part of mutt-ng, see http://www.muttng.org/.
6 * It's licensed under the GNU General Public License,
7 * please see the file GPL in the top level source directory.
26 int _mutt_system (const char *cmd, int flags)
30 struct sigaction oldtstp;
31 struct sigaction oldcont;
38 /* must ignore SIGINT and SIGQUIT */
40 mutt_block_signals_system ();
42 /* also don't want to be stopped right now */
43 if (flags & M_DETACH_PROCESS) {
45 sigaddset (&set, SIGTSTP);
46 sigprocmask (SIG_BLOCK, &set, NULL);
49 act.sa_handler = SIG_DFL;
50 /* we want to restart the waitpid() below */
52 act.sa_flags = SA_RESTART;
54 sigemptyset (&act.sa_mask);
55 sigaction (SIGTSTP, &act, &oldtstp);
56 sigaction (SIGCONT, &act, &oldcont);
59 if ((thepid = fork ()) == 0) {
62 if (flags & M_DETACH_PROCESS) {
65 /* give up controlling terminal */
71 for (fd = 0; fd < OPEN_MAX; fd++)
73 #elif defined(_POSIX_OPEN_MAX)
74 for (fd = 0; fd < _POSIX_OPEN_MAX; fd++)
82 act.sa_handler = SIG_DFL;
83 sigaction (SIGCHLD, &act, NULL);
94 /* reset signals for the child; not really needed, but... */
95 mutt_unblock_signals_system (0);
96 act.sa_handler = SIG_DFL;
98 sigemptyset (&act.sa_mask);
99 sigaction (SIGTERM, &act, NULL);
100 sigaction (SIGTSTP, &act, NULL);
101 sigaction (SIGCONT, &act, NULL);
103 execl (EXECSHELL, "sh", "-c", cmd, NULL);
104 _exit (127); /* execl error */
106 else if (thepid != -1) {
108 /* wait for the (first) child process to finish */
109 waitpid (thepid, &rc, 0);
111 rc = imap_wait_keepalive (thepid);
115 sigaction (SIGCONT, &oldcont, NULL);
116 sigaction (SIGTSTP, &oldtstp, NULL);
118 /* reset SIGINT, SIGQUIT and SIGCHLD */
119 mutt_unblock_signals_system (1);
120 if (flags & M_DETACH_PROCESS)
121 sigprocmask (SIG_UNBLOCK, &set, NULL);
123 rc = (thepid != -1) ? (WIFEXITED (rc) ? WEXITSTATUS (rc) : -1) : -1;