Invoke sendmail in a subshell.
92{
93 sigset_t set;
94 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
169
171 execvp(path, (char **) args->entries);
173 }
174 else if (pid == -1)
175 {
176 unlink(msg);
179 }
180
181
182
183
184 if (wait_time > 0)
185 {
188#ifdef SA_INTERRUPT
189
190 act.sa_flags = SA_INTERRUPT;
191#else
192 act.sa_flags = 0;
193#endif
194 sigemptyset(&act.sa_mask);
195 sigaction(SIGALRM, &act, &oldalrm);
196 alarm(wait_time);
197 }
198 else if (wait_time < 0)
199 {
201 }
202
203 if (waitpid(pid, &st, 0) > 0)
204 {
205 st = WIFEXITED(st) ? WEXITSTATUS(st) :
S_ERR;
206 if (wait_time && (st == (0xff &
EX_OK)) && tempfile && *tempfile)
207 {
208 unlink(*tempfile);
210 }
211 }
212 else
213 {
215 if ((wait_time > 0) && tempfile && *tempfile)
216 {
217 unlink(*tempfile);
219 }
220 }
221
222 if (wait_time > 0)
223 {
224
225 alarm(0);
226 sigaction(SIGALRM, &oldalrm, NULL);
227 }
228
229 if ((kill(ppid, 0) == -1) && (errno == ESRCH) && tempfile && *tempfile)
230 {
231
232 unlink(*tempfile);
234 }
235
236 _exit(st);
237 }
238
239 sigprocmask(SIG_UNBLOCK, &set, NULL);
240
241 if ((pid != -1) && (waitpid(pid, &st, 0) > 0))
242 st = WIFEXITED(st) ? WEXITSTATUS(st) :
S_ERR;
243 else
245
247
248 return st;
249}
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_block_system(void)
Block signals before calling exec()
void mutt_sig_unblock_system(bool restore)
Restore previously blocked signals.
String manipulation buffer.