8 /* Advice about children from Peter:
9 Better way: before the fork, make a pipe. In the child close the
10 +reading end. Make the writing end close-on-exec. If the dup2 or exec fails,
11 +write the errno value. In the parent, close the writing end. Now you can read
12 +from it. If you get an errno value from the pipe, the process failed and you
13 +know why. If you get EOF, the exec succeeded.
15 <Senji> So, close on exec only closes if exec isn't going to return then?
16 <Diziet> qu: I wouldn't bother with all that with pipes. Remember that the
17 +runtime system can still make exec fail when it's `too late'.
18 <Senji> Diz - I would rather have a coherant error message than 'child failed'
19 <Diziet> The child, if it fails to exec, should print a message to stderr
20 +(giving errno and what it was trying to execute, most likely), and exit
22 <Diziet> It should exit calling _exit.
25 /* Process handling - subprocesses, signals, etc. */
27 static bool_t signal_handling=False;
28 static sigset_t emptyset, fullset;
29 static sigset_t registered,pending;
34 process_callback_fn *cb;
40 static struct child *children=NULL;
44 signal_notify_fn *notify;
46 struct signotify *next;
49 static struct signotify *sigs=NULL;
51 static int spw,spr; /* file descriptors for signal notification pipe */
53 static void set_default_signals(void);
55 /* Long-lived subprocesses can only be started once we've started
56 signal processing so that we can catch SIGCHLD for them and report
57 their exit status using the callback function. We block SIGCHLD
58 until signal processing has begun. */
59 pid_t makesubproc(process_entry_fn *entry, process_callback_fn *cb,
60 void *est, void *cst, cstring_t desc)
65 c=safe_malloc(sizeof(*c),"makesubproc");
70 if (!signal_handling) {
71 fatal("makesubproc called before signal handling started");
76 set_default_signals();
77 sigprocmask(SIG_SETMASK,&emptyset,NULL);
81 fatal_perror("makesubproc (%s): fork",desc);
90 static signal_notify_fn sigchld_handler;
91 static void sigchld_handler(void *st, int signum)
93 struct child *i,*n,**p;
96 process_callback_fn *cb;
101 struct work *w=NULL, *nw;
105 for (i=children; i; i=i->next) {
106 rv=waitpid(i->pid,&status,WNOHANG);
108 fatal_perror("sigchld_handler: waitpid");
113 nw=safe_malloc(sizeof(*nw),"sigchld_handler");
123 /* Remove all the finished tasks from the list of children */
124 for (i=children, p=&children; i; i=n) {
134 /* Notify as appropriate, then free the list */
136 w->cb(w->cst,w->pid,w->status);
143 int sys_cmd(const char *path, const char *arg, ...)
152 /* Parent -> wait for child */
157 /* Child -> exec command */
158 /* Really we ought to strcpy() the arguments into the args array,
159 since the arguments are const char *. Since we'll exit anyway
160 if the execvp() fails this seems somewhat pointless, and
161 increases the chance of the child process failing before it
165 while ((args[i++]=va_arg(ap,char *)));
170 fatal_perror("sys_cmd(%s,%s,...)");
177 static beforepoll_fn signal_beforepoll;
178 static int signal_beforepoll(void *st, struct pollfd *fds, int *nfds_io,
187 fds[0].events=POLLIN;
191 static afterpoll_fn signal_afterpoll;
192 static void signal_afterpoll(void *st, struct pollfd *fds, int nfds)
198 if (nfds && (fds->revents & POLLIN)) {
199 read(spr,buf,16); /* We don't actually care what we read; as
200 long as there was at least one byte
201 (which there was) we'll pick up the
202 signals in the pending set */
204 /* We reset 'pending' before processing any of the signals
205 that were pending so that we don't miss any signals that
206 are delivered partway-through processing (all we assume
207 about signal notification routines is that they handle all
208 the work available at their _start_ and only optionally any
209 work that arrives part-way through their execution). */
210 sigprocmask(SIG_SETMASK,&fullset,&old);
212 sigemptyset(&pending);
213 sigprocmask(SIG_SETMASK,&old,NULL);
215 for (n=sigs; n; n=n->next)
216 if (sigismember(&todo,n->signum))
217 n->notify(n->cst,n->signum);
221 static void set_default_signals(void)
228 for (n=sigs; n; n=n->next)
229 if (!sigismember(&done,n->signum)) {
230 sigaddset(&done,n->signum);
231 sa.sa_handler=SIG_DFL;
234 sigaction(n->signum,&sa,NULL);
238 static void signal_handler(int signum)
242 sigaddset(&pending,signum);
243 /* XXX the write() may set errno, which can make the main program fail.
244 However, signal handlers aren't allowed to modify anything which
245 is not of type sig_atomic_t. The world is broken. */
246 /* I have decided to save and restore errno anyway; on most
247 architectures on which secnet can run modifications to errno
248 will be atomic, and it seems to be the lesser of the two
251 write(spw,&thing,1); /* We don't care if this fails (i.e. the pipe
252 is full) because the service routine will
253 spot the pending signal anyway */
257 static void register_signal_handler(struct signotify *s)
262 if (!signal_handling) return;
264 if (sigismember(®istered,s->signum)) return;
265 sigaddset(®istered,s->signum);
267 sa.sa_handler=signal_handler;
270 rv=sigaction(s->signum,&sa,NULL);
272 fatal_perror("register_signal_handler: sigaction(%d)",s->signum);
276 void request_signal_notification(int signum, signal_notify_fn *notify,
282 s=safe_malloc(sizeof(*s),"request_signal_notification");
287 sigprocmask(SIG_SETMASK,&fullset,&old);
289 register_signal_handler(s);
290 sigprocmask(SIG_SETMASK,&old,NULL);
293 void start_signal_handling(void)
298 sigemptyset(&emptyset);
299 sigfillset(&fullset);
300 sigemptyset(®istered);
301 sigemptyset(&pending);
304 fatal_perror("start_signal_handling: pipe");
308 if (fcntl(spw, F_SETFL, fcntl(spw, F_GETFL)|O_NONBLOCK)==-1) {
309 fatal_perror("start_signal_handling: fcntl(O_NONBLOCK)");
312 register_for_poll(NULL,signal_beforepoll,signal_afterpoll,1,"signal");
313 signal_handling=True;
315 /* Register signal handlers for all the signals we're interested in */
316 for (i=sigs; i; i=i->next) {
317 register_signal_handler(i);
320 request_signal_notification(SIGCHLD,sigchld_handler,NULL);