X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?p=secnet.git;a=blobdiff_plain;f=process.c;h=c14dd694d977afe51dd742c9428303890cb4869d;hp=0a718e20b443e5827d59762602e162300b272df8;hb=7cafb08048979850a82b43059b48b947bc2fa9bc;hpb=32fc582f43a9a3841d2782674e055113729c2814 diff --git a/process.c b/process.c index 0a718e2..c14dd69 100644 --- a/process.c +++ b/process.c @@ -35,8 +35,6 @@ static struct signotify *sigs=NULL; static int spw,spr; /* file descriptors for signal notification pipe */ -static void set_default_signals(void); - /* Long-lived subprocesses can only be started once we've started signal processing so that we can catch SIGCHLD for them and report their exit status using the callback function. We block SIGCHLD @@ -58,8 +56,7 @@ pid_t makesubproc(process_entry_fn *entry, process_callback_fn *cb, p=fork(); if (p==0) { /* Child process */ - set_default_signals(); - sigprocmask(SIG_SETMASK,&emptyset,NULL); + afterfork(); entry(est); abort(); } else if (p==-1) { @@ -143,17 +140,8 @@ int sys_cmd(const char *path, const char *arg, ...) fatal("sys_cmd: waitpid for %s returned wrong process ID!", path); if (rv) { - /* If the command failed reporting its exit status */ - if (WIFEXITED(rv)) - Message(M_ERR, "sys_cmd(%s,%s,...) exited with status %d\n", - path, arg, WEXITSTATUS(rv)); - else if(WIFSIGNALED(rv)) - Message(M_ERR, "sys_cmd(%s,%s,...) exited with signal %d (%s)%s\n", - path, arg, WTERMSIG(rv), strsignal(WTERMSIG(rv)), - WCOREDUMP(rv) ? " - core dumped" : ""); - else - Message(M_ERR, "sys_cmd(%s,%s,...) exited with wstat %#x\n", - path, arg, rv); + /* If the command failed report its exit status */ + lg_exitstatus(0,"sys_cmd",0,M_ERR,rv,path); } } else if (c==0) { char *args[100]; @@ -164,6 +152,7 @@ int sys_cmd(const char *path, const char *arg, ...) if the execvp() fails this seems somewhat pointless, and increases the chance of the child process failing before it gets to exec(). */ + afterfork(); va_start(ap,arg); args[0]=(char *)arg; /* program name */ i=1; @@ -223,12 +212,16 @@ static void signal_afterpoll(void *st, struct pollfd *fds, int nfds) } } -static void set_default_signals(void) +void afterfork(void) { struct signotify *n; sigset_t done; struct sigaction sa; + clear_phase_hooks(PHASE_SHUTDOWN); + /* Prevents calls to fatal() etc. in the child from running off + and doing a lot of unhelpful things */ + sigemptyset(&done); for (n=sigs; n; n=n->next) if (!sigismember(&done,n->signum)) { @@ -238,6 +231,19 @@ static void set_default_signals(void) sa.sa_flags=0; sigaction(n->signum,&sa,NULL); } + + sigemptyset(&emptyset); + sigprocmask(SIG_SETMASK,&emptyset,NULL); +} + +void childpersist_closefd_hook(void *fd_vp, uint32_t newphase) +{ + int *fd_p=fd_vp; + int fd=*fd_p; + if (fd<0) return; + *fd_p=-1; + setnonblock(fd); /* in case close() might block */ + close(fd); /* discard errors - we don't care, in the child */ } static void signal_handler(int signum) @@ -309,9 +315,8 @@ void start_signal_handling(void) pipe_cloexec(p); spw=p[1]; spr=p[0]; - if (fcntl(spw, F_SETFL, fcntl(spw, F_GETFL)|O_NONBLOCK)==-1) { - fatal_perror("start_signal_handling: fcntl(O_NONBLOCK)"); - } + setnonblock(spw); + setnonblock(spr); register_for_poll(NULL,signal_beforepoll,signal_afterpoll,"signal"); signal_handling=True;