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, string_t desc)
65 c=safe_malloc(sizeof(*c),"makesubproc");
70 if (!signal_handling) {
71 fatal("makesubproc called before signal handling started\n");
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, char *arg, ...)
152 /* Parent -> wait for child */
157 /* Child -> exec command */
160 while ((args[i++]=va_arg(ap,char *)));
165 fatal_perror("sys_cmd(%s,%s,...)");
172 static beforepoll_fn signal_beforepoll;
173 static int signal_beforepoll(void *st, struct pollfd *fds, int *nfds_io,
174 int *timeout_io, const struct timeval *tv_now,
183 fds[0].events=POLLIN;
187 static afterpoll_fn signal_afterpoll;
188 static void signal_afterpoll(void *st, struct pollfd *fds, int nfds,
189 const struct timeval *tv, uint64_t *now)
195 if (nfds && (fds->revents & POLLIN)) {
196 read(spr,buf,16); /* We don't actually care what we read; as
197 long as there was at least one byte
198 (which there was) we'll pick up the
199 signals in the pending set */
201 /* We reset 'pending' before processing any of the signals
202 that were pending so that we don't miss any signals that
203 are delivered partway-through processing (all we assume
204 about signal notification routines is that they handle all
205 the work available at their _start_ and only optionally any
206 work that arrives part-way through their execution). */
207 sigprocmask(SIG_SETMASK,&fullset,&old);
209 sigemptyset(&pending);
210 sigprocmask(SIG_SETMASK,&old,NULL);
212 for (n=sigs; n; n=n->next)
213 if (sigismember(&todo,n->signum))
214 n->notify(n->cst,n->signum);
218 static void set_default_signals(void)
225 for (n=sigs; n; n=n->next)
226 if (!sigismember(&done,n->signum)) {
227 sigaddset(&done,n->signum);
228 sa.sa_handler=SIG_DFL;
231 sigaction(n->signum,&sa,NULL);
235 static void signal_handler(int signum)
238 sigaddset(&pending,signum);
239 write(spw,&thing,1); /* We don't care if this fails (i.e. the pipe
240 is full) because the service routine will
241 spot the pending signal anyway */
244 static void register_signal_handler(struct signotify *s)
249 if (!signal_handling) return;
251 if (sigismember(®istered,s->signum)) return;
252 sigaddset(®istered,s->signum);
254 sa.sa_handler=signal_handler;
257 rv=sigaction(s->signum,&sa,NULL);
259 fatal_perror("register_signal_handler: sigaction(%d)",s->signum);
263 void request_signal_notification(int signum, signal_notify_fn *notify,
269 s=safe_malloc(sizeof(*s),"request_signal_notification");
274 sigprocmask(SIG_SETMASK,&fullset,&old);
276 register_signal_handler(s);
277 sigprocmask(SIG_SETMASK,&old,NULL);
280 void start_signal_handling(void)
285 sigemptyset(&emptyset);
286 sigfillset(&fullset);
287 sigemptyset(®istered);
288 sigemptyset(&pending);
291 fatal_perror("start_signal_handling: pipe");
295 if (fcntl(spw, F_SETFL, fcntl(spw, F_GETFL)|O_NONBLOCK)==-1) {
296 fatal_perror("start_signal_handling: fcntl(O_NONBLOCK)");
299 register_for_poll(NULL,signal_beforepoll,signal_afterpoll,1,"signal");
300 signal_handling=True;
302 /* Register signal handlers for all the signals we're interested in */
303 for (i=sigs; i; i=i->next) {
304 register_signal_handler(i);
307 request_signal_notification(SIGCHLD,sigchld_handler,NULL);