Invoke sendmail in a subshell.
93{
94 sigset_t set;
95 int st;
96
98
99 sigemptyset(&set);
100
101 sigaddset(&set, SIGTSTP);
102 sigprocmask(SIG_BLOCK, &set, NULL);
103
104 if ((wait_time >= 0) && tempfile)
105 {
110 }
111
112 pid_t pid = fork();
113 if (pid == 0)
114 {
115 struct sigaction act = { 0 };
116 struct sigaction oldalrm = { 0 };
117
118
119 pid_t ppid = getppid();
120
121
122
123 setsid();
124
125
126 close(0);
127#ifdef OPEN_MAX
128 for (int fd = tempfile ? 1 : 3; fd < OPEN_MAX; fd++)
129 close(fd);
130#elif defined(_POSIX_OPEN_MAX)
131 for (int fd = tempfile ? 1 : 3; fd < _POSIX_OPEN_MAX; fd++)
132 close(fd);
133#else
134 if (tempfile)
135 {
136 close(1);
137 close(2);
138 }
139#endif
140
141
142 pid = fork();
143 if (pid == 0)
144 {
145
146 if (open(msg, O_RDONLY, 0) < 0)
147 {
148 unlink(msg);
150 }
151 unlink(msg);
152
153 if ((wait_time >= 0) && tempfile && *tempfile)
154 {
155
156 if (open(*tempfile, O_WRONLY | O_APPEND | O_CREAT | O_EXCL, 0600) < 0)
158
159 if (dup(1) < 0)
161 }
162 else if (tempfile)
163 {
164 if (open("/dev/null", O_WRONLY | O_APPEND) < 0)
166 if (open("/dev/null", O_RDWR | O_APPEND) < 0)
168 }
169
171
172
174 execvp(path, (char **) args->entries);
176 }
177 else if (pid == -1)
178 {
179 unlink(msg);
182 }
183
184
185
186
187 if (wait_time > 0)
188 {
191#ifdef SA_INTERRUPT
192
193 act.sa_flags = SA_INTERRUPT;
194#else
195 act.sa_flags = 0;
196#endif
197 sigemptyset(&act.sa_mask);
198 sigaction(SIGALRM, &act, &oldalrm);
199 alarm(wait_time);
200 }
201 else if (wait_time < 0)
202 {
204 }
205
206 if (waitpid(pid, &st, 0) > 0)
207 {
208 st = WIFEXITED(st) ? WEXITSTATUS(st) :
S_ERR;
209 if (wait_time && (st == (0xff &
EX_OK)) && tempfile && *tempfile)
210 {
211 unlink(*tempfile);
213 }
214 }
215 else
216 {
218 if ((wait_time > 0) && tempfile && *tempfile)
219 {
220 unlink(*tempfile);
222 }
223 }
224
225 if (wait_time > 0)
226 {
227
228 alarm(0);
229 sigaction(SIGALRM, &oldalrm, NULL);
230 }
231
232 if ((kill(ppid, 0) == -1) && (errno == ESRCH) && tempfile && *tempfile)
233 {
234
235 unlink(*tempfile);
237 }
238
239 _exit(st);
240 }
241
242 sigprocmask(SIG_UNBLOCK, &set, NULL);
243
244 if ((pid != -1) && (waitpid(pid, &st, 0) > 0))
245 st = WIFEXITED(st) ? WEXITSTATUS(st) :
S_ERR;
246 else
248
250
251 return st;
252}
char * buf_strdup(const struct Buffer *buf)
Copy a Buffer's string.
char ** EnvList
Private copy of the environment variables.
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.