From: Ian Jackson Date: Sat, 1 May 2010 13:26:38 +0000 (+0100) Subject: reset TERM and INT in child (and act on any that arrived between fork and reset) X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?p=inn-innduct.git;a=commitdiff_plain;h=780c1d174bed4a92d1e08f943ddcc77d8104b999 reset TERM and INT in child (and act on any that arrived between fork and reset) --- diff --git a/backends/innduct.c b/backends/innduct.c index a1c7491..f1f8fd4 100644 --- a/backends/innduct.c +++ b/backends/innduct.c @@ -1,7 +1,5 @@ /* * todo - * - reset signals TERM and INT (and HUP) in children - * * - manpage: document control master stuff * - admin-initiated flush * @@ -208,6 +206,7 @@ perl -ne 'print if m/-8\<-/..m/-\>8-/; print "\f" if m/-\^L-/' backends/innduct. #define VA va_list al; va_start(al,fmt) #define PRINTF(f,a) __attribute__((__format__(printf,f,a))) #define NORET_PRINTF(f,a) __attribute__((__noreturn__,__format__(printf,f,a))) +#define NORET __attribute__((__noreturn__)) #define NEW(ptr) ((ptr)= zxmalloc(sizeof(*(ptr)))) #define NEW_DECL(type,ptr) type ptr = zxmalloc(sizeof(*(ptr))) @@ -314,7 +313,7 @@ static void open_defer(void); static void close_defer(void); static void search_backlog_file(void); static void preterminate(void); -static void raise_default(int signo); +static void raise_default(int signo) NORET; static char *debug_report_ipf(InputFile *ipf); static void inputfile_reading_start(InputFile *ipf); @@ -678,9 +677,16 @@ static time_t xtime(void) { return now; } -static void xsigaction(int s, const struct sigaction *sa) { - int r= sigaction(s,sa,0); - if (r) sysdie("sigaction failed for \"%s\"", strsignal(s)); +static void xsigaction(int signo, const struct sigaction *sa) { + int r= sigaction(signo,sa,0); + if (r) sysdie("sigaction failed for \"%s\"", strsignal(signo)); +} + +static void xsigsetdefault(int signo) { + struct sigaction sa; + memset(&sa,0,sizeof(sa)); + sa.sa_handler= SIG_DFL; + xsigaction(signo,&sa); } static void xgettimeofday(struct timeval *tv_r) { @@ -2786,11 +2792,9 @@ static int signal_self_pipe[2]; static sig_atomic_t terminate_sig_flag; static void raise_default(int signo) { - struct sigaction sa; - memset(&sa,0,sizeof(sa)); - sa.sa_handler= SIG_DFL; - xsigaction(signo,&sa); + xsigsetdefault(signo); raise(signo); + abort(); } static void *sigarrived_event(oop_source *lp, int fd, oop_event e, void *u) { @@ -2803,7 +2807,6 @@ static void *sigarrived_event(oop_source *lp, int fd, oop_event e, void *u) { preterminate(); notice("terminating (%s)", strsignal(terminate_sig_flag)); raise_default(terminate_sig_flag); - abort(); } return OOP_CONTINUE; } @@ -2811,7 +2814,8 @@ static void *sigarrived_event(oop_source *lp, int fd, oop_event e, void *u) { static void sigarrived_handler(int signum) { static char x; switch (signum) { - case SIGINT: case SIGTERM: + case SIGTERM: + case SIGINT: if (!terminate_sig_flag) terminate_sig_flag= signum; break; default: @@ -2983,8 +2987,10 @@ static void postfork_stdio(FILE *f, const char *what, const char *what2) { static void postfork(void) { in_child= 1; - if (signal(SIGPIPE, SIG_DFL) == SIG_ERR) - sysdie("(in child) failed to reset SIGPIPE"); + xsigsetdefault(SIGTERM); + xsigsetdefault(SIGINT); + xsigsetdefault(SIGPIPE); + if (terminate_sig_flag) raise(terminate_sig_flag); postfork_inputfile(main_input_file); postfork_inputfile(flushing_input_file);