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