Invoke sendmail in a subshell.
91{
92 sigset_t set;
93 int st;
94
96
97 sigemptyset(&set);
98
99 sigaddset(&set, SIGTSTP);
100 sigprocmask(SIG_BLOCK, &set, NULL);
101
102 if ((wait_time >= 0) && tempfile)
103 {
108 }
109
110 pid_t pid = fork();
111 if (pid == 0)
112 {
113 struct sigaction act = { 0 };
114 struct sigaction oldalrm = { 0 };
115
116
117 pid_t ppid = getppid();
118
119
120
121 setsid();
122
123
124 close(0);
125#ifdef OPEN_MAX
126 for (int fd = tempfile ? 1 : 3; fd < OPEN_MAX; fd++)
127 close(fd);
128#elif defined(_POSIX_OPEN_MAX)
129 for (int fd = tempfile ? 1 : 3; fd < _POSIX_OPEN_MAX; fd++)
130 close(fd);
131#else
132 if (tempfile)
133 {
134 close(1);
135 close(2);
136 }
137#endif
138
139
140 pid = fork();
141 if (pid == 0)
142 {
143
144 if (open(msg, O_RDONLY, 0) < 0)
145 {
146 unlink(msg);
148 }
149 unlink(msg);
150
151 if ((wait_time >= 0) && tempfile && *tempfile)
152 {
153
154 if (open(*tempfile, O_WRONLY | O_APPEND | O_CREAT | O_EXCL, 0600) < 0)
156
157 if (dup(1) < 0)
159 }
160 else if (tempfile)
161 {
162 if (open("/dev/null", O_WRONLY | O_APPEND) < 0)
164 if (open("/dev/null", O_RDWR | O_APPEND) < 0)
166 }
167
169
170
172 execvp(path, (char **) args->entries);
174 }
175 else if (pid == -1)
176 {
177 unlink(msg);
180 }
181
182
183
184
185 if (wait_time > 0)
186 {
189#ifdef SA_INTERRUPT
190
191 act.sa_flags = SA_INTERRUPT;
192#else
193 act.sa_flags = 0;
194#endif
195 sigemptyset(&act.sa_mask);
196 sigaction(SIGALRM, &act, &oldalrm);
197 alarm(wait_time);
198 }
199 else if (wait_time < 0)
200 {
202 }
203
204 if (waitpid(pid, &st, 0) > 0)
205 {
206 st = WIFEXITED(st) ? WEXITSTATUS(st) :
S_ERR;
207 if (wait_time && (st == (0xff &
EX_OK)) && tempfile && *tempfile)
208 {
209 unlink(*tempfile);
211 }
212 }
213 else
214 {
216 if ((wait_time > 0) && tempfile && *tempfile)
217 {
218 unlink(*tempfile);
220 }
221 }
222
223 if (wait_time > 0)
224 {
225
226 alarm(0);
227 sigaction(SIGALRM, &oldalrm, NULL);
228 }
229
230 if ((kill(ppid, 0) == -1) && (errno == ESRCH) && tempfile && *tempfile)
231 {
232
233 unlink(*tempfile);
235 }
236
237 _exit(st);
238 }
239
240 sigprocmask(SIG_UNBLOCK, &set, NULL);
241
242 if ((pid != -1) && (waitpid(pid, &st, 0) > 0))
243 st = WIFEXITED(st) ? WEXITSTATUS(st) :
S_ERR;
244 else
246
248
249 return st;
250}
char * buf_strdup(const struct Buffer *buf)
Copy a Buffer's string.
struct Buffer * buf_pool_get(void)
Get a Buffer from the pool.
void buf_pool_release(struct Buffer **ptr)
Return a Buffer to the pool.
static void alarm_handler(int sig)
Async notification of an alarm signal.
void mutt_sig_reset_child_signals(void)
Reset ignored signals back to the default.
void mutt_sig_block_system(void)
Block signals before calling exec()
void mutt_sig_unblock_system(bool restore)
Restore previously blocked signals.
String manipulation buffer.
Container for Accounts, Notifications.
char ** env
Private copy of the environment variables.