chiark / gitweb /
reset TERM and INT in child (and act on any that arrived between fork and reset)
authorIan Jackson <ian@liberator.relativity.greenend.org.uk>
Sat, 1 May 2010 13:26:38 +0000 (14:26 +0100)
committerIan Jackson <ian@liberator.relativity.greenend.org.uk>
Sat, 1 May 2010 13:26:38 +0000 (14:26 +0100)
backends/innduct.c

index a1c7491..f1f8fd4 100644 (file)
@@ -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);