2 * Copyright notice from original mutt:
3 * Copyright (C) 1996-2000 Michael R. Elkins <me@mutt.org>
4 * Copyright (C) 1999-2000 Thomas Roessler <roessler@does-not-exist.org>
6 * This file is part of mutt-ng, see http://www.muttng.org/.
7 * It's licensed under the GNU General Public License,
8 * please see the file GPL in the top level source directory.
16 #include <lib-lib/macros.h>
17 #include <lib-lib/mem.h>
18 #include <lib-lib/str.h>
21 #include "mutt_signal.h"
23 #include <imap/imap.h> /* for imap_wait_keepalive EEEEK */
26 /* Extract the real name from /etc/passwd's GECOS field.
27 * When set, honor the regular expression in rx,
28 * otherwise assume that the GECOS field is a comma-separated list.
29 * Replace "&" by a capitalized version of the user's login name.
31 ssize_t mutt_gecos_name(char *dst, ssize_t n, struct passwd *pw, rx_t *rx)
43 regmatch_t pat_match[1];
45 if (regexec(rx->rx, pw->pw_gecos, 1, pat_match, 0)) {
49 p = pw->pw_gecos + pat_match[0].rm_so;
50 end = pw->pw_gecos + pat_match[0].rm_so;
53 end = m_strchrnul(pw->pw_gecos, ',');
57 const char *q = MIN(end, m_strchrnul(p, '&'));
59 len += m_strncpy(dst + len, n - len, p, q - p);
62 if (!p[-1] || p >= end)
66 len += m_strcpy(dst + len, n - len, pw->pw_name);
72 int _mutt_system(const char *cmd, int flags)
76 struct sigaction oldtstp;
77 struct sigaction oldcont;
81 if (m_strisempty(cmd))
84 /* must ignore SIGINT and SIGQUIT */
85 mutt_block_signals_system();
87 /* also don't want to be stopped right now */
88 if (flags & M_DETACH_PROCESS) {
90 sigaddset(&set, SIGTSTP);
91 sigprocmask(SIG_BLOCK, &set, NULL);
93 act.sa_handler = SIG_DFL;
94 /* we want to restart the waitpid() below */
96 act.sa_flags = SA_RESTART;
98 sigemptyset(&act.sa_mask);
99 sigaction(SIGTSTP, &act, &oldtstp);
100 sigaction(SIGCONT, &act, &oldcont);
107 if (flags & M_DETACH_PROCESS) {
108 /* give up controlling terminal */
115 nb_fds = getdtablesize();
116 for (fd = 0; fd < nb_fds; fd++) {
120 act.sa_handler = SIG_DFL;
121 sigaction(SIGCHLD, &act, NULL);
132 /* reset signals for the child; not really needed, but... */
133 mutt_unblock_signals_system(0);
134 act.sa_handler = SIG_DFL;
136 sigemptyset(&act.sa_mask);
137 sigaction(SIGTERM, &act, NULL);
138 sigaction(SIGTSTP, &act, NULL);
139 sigaction(SIGCONT, &act, NULL);
141 execl("/bin/sh", "sh", "-c", cmd, NULL);
142 _exit(127); /* execl error */
145 rc = imap_wait_keepalive(pid);
148 sigaction(SIGCONT, &oldcont, NULL);
149 sigaction(SIGTSTP, &oldtstp, NULL);
151 /* reset SIGINT, SIGQUIT and SIGCHLD */
152 mutt_unblock_signals_system(1);
153 if (flags & M_DETACH_PROCESS) {
154 sigprocmask (SIG_UNBLOCK, &set, NULL);
157 return (pid > 0 && WIFEXITED(rc)) ? WEXITSTATUS(rc) : -1;