NeoMutt  2019-12-07-60-g0cfa53
Teaching an old dog new tricks
DOXYGEN
system.c
Go to the documentation of this file.
1 
29 #include "config.h"
30 #include <signal.h>
31 #include <stdbool.h>
32 #include <stdlib.h>
33 #include <sys/wait.h> // IWYU pragma: keep
34 #include <unistd.h>
35 #include "mutt/mutt.h"
36 #include "mutt.h"
37 #include "protos.h" // IWYU pragma: keep
38 #ifdef USE_IMAP
39 #include "imap/imap.h"
40 #endif
41 
52 int mutt_system(const char *cmd)
53 {
54  int rc = -1;
55  struct sigaction act;
56  struct sigaction oldtstp;
57  struct sigaction oldcont;
58  pid_t pid;
59 
60  if (!cmd || !*cmd)
61  return 0;
62 
63  /* must ignore SIGINT and SIGQUIT */
64 
66 
67  act.sa_handler = SIG_DFL;
68 /* we want to restart the waitpid() below */
69 #ifdef SA_RESTART
70  act.sa_flags = SA_RESTART;
71 #endif
72  sigemptyset(&act.sa_mask);
73  sigaction(SIGTSTP, &act, &oldtstp);
74  sigaction(SIGCONT, &act, &oldcont);
75 
76  pid = fork();
77  if (pid == 0)
78  {
79  act.sa_flags = 0;
80 
81  /* reset signals for the child; not really needed, but... */
83  act.sa_handler = SIG_DFL;
84  act.sa_flags = 0;
85  sigemptyset(&act.sa_mask);
86  sigaction(SIGTERM, &act, NULL);
87  sigaction(SIGTSTP, &act, NULL);
88  sigaction(SIGCONT, &act, NULL);
89 
90  execle(EXEC_SHELL, "sh", "-c", cmd, NULL, mutt_envlist_getlist());
91  _exit(127); /* execl error */
92  }
93  else if (pid != -1)
94  {
95 #ifdef USE_IMAP
96  rc = imap_wait_keepalive(pid);
97 #endif
98  }
99 
100  sigaction(SIGCONT, &oldcont, NULL);
101  sigaction(SIGTSTP, &oldtstp, NULL);
102 
103  /* reset SIGINT, SIGQUIT and SIGCHLD */
105 
106  rc = (pid != -1) ? (WIFEXITED(rc) ? WEXITSTATUS(rc) : -1) : -1;
107 
108  return rc;
109 }
void mutt_sig_block_system(void)
Block signals before calling exec()
Definition: signal.c:183
void mutt_sig_unblock_system(bool restore)
Restore previously blocked signals.
Definition: signal.c:207
IMAP network mailbox.
#define EXEC_SHELL
Definition: mutt.h:124
Prototypes for many functions.
int mutt_system(const char *cmd)
Run an external command.
Definition: system.c:52
Convenience wrapper for the library headers.
int imap_wait_keepalive(pid_t pid)
Wait for a process to change state.
Definition: util.c:1090
char ** mutt_envlist_getlist(void)
Get the private environment.
Definition: envlist.c:169