Invoke sendmail in a subshell.
91{
92 sigset_t set;
93 int st;
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 == 0)
113 {
114 struct sigaction act = { 0 };
115 struct sigaction oldalrm = { 0 };
116
117
118 pid_t ppid = getppid();
119
120
121
122 setsid();
123
124
125 close(0);
126#ifdef OPEN_MAX
127 for (int fd = tempfile ? 1 : 3; fd < OPEN_MAX; fd++)
128 close(fd);
129#elif defined(_POSIX_OPEN_MAX)
130 for (int fd = tempfile ? 1 : 3; fd < _POSIX_OPEN_MAX; fd++)
131 close(fd);
132#else
133 if (tempfile)
134 {
135 close(1);
136 close(2);
137 }
138#endif
139
140
141 pid = fork();
142 if (pid == 0)
143 {
144
145 if (open(msg, O_RDONLY, 0) < 0)
146 {
147 unlink(msg);
149 }
150 unlink(msg);
151
152 if ((wait_time >= 0) && tempfile && *tempfile)
153 {
154
155 if (open(*tempfile, O_WRONLY | O_APPEND | O_CREAT | O_EXCL, 0600) < 0)
157
158 if (dup(1) < 0)
160 }
161 else if (tempfile)
162 {
163 if (open("/dev/null", O_WRONLY | O_APPEND) < 0)
165 if (open("/dev/null", O_RDWR | O_APPEND) < 0)
167 }
168
170
171
173 execvp(path, (char **) args->entries);
175 }
176 else if (pid == -1)
177 {
178 unlink(msg);
181 }
182
183
184
185
186 if (wait_time > 0)
187 {
190#ifdef SA_INTERRUPT
191
192 act.sa_flags = SA_INTERRUPT;
193#else
194 act.sa_flags = 0;
195#endif
196 sigemptyset(&act.sa_mask);
197 sigaction(SIGALRM, &act, &oldalrm);
198 alarm(wait_time);
199 }
200 else if (wait_time < 0)
201 {
203 }
204
205 if (waitpid(pid, &st, 0) > 0)
206 {
207 st = WIFEXITED(st) ? WEXITSTATUS(st) :
S_ERR;
208 if (wait_time && (st == (0xff &
EX_OK)) && tempfile && *tempfile)
209 {
210 unlink(*tempfile);
212 }
213 }
214 else
215 {
217 if ((wait_time > 0) && tempfile && *tempfile)
218 {
219 unlink(*tempfile);
221 }
222 }
223
224 if (wait_time > 0)
225 {
226
227 alarm(0);
228 sigaction(SIGALRM, &oldalrm, NULL);
229 }
230
231 if ((kill(ppid, 0) == -1) && (errno == ESRCH) && tempfile && *tempfile)
232 {
233
234 unlink(*tempfile);
236 }
237
238 _exit(st);
239 }
240
241 sigprocmask(SIG_UNBLOCK, &set, NULL);
242
243 if ((pid != -1) && (waitpid(pid, &st, 0) > 0))
244 st = WIFEXITED(st) ? WEXITSTATUS(st) :
S_ERR;
245 else
247
249
250 return st;
251}
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.