Submitted by: Damon Harper Date: 2006-08-26, 2007-09-21 Summary: Fix SIGCHLD handling in comsatd This patch fixes a problem with comsatd where child processes spawned by .biffrc commands complain because SIGCHLD has been ignored. For example, when calling a perl script with SIGCHLD ignored, perl generates the following error on stderr, which then gets echoed to the tty: Can't ignore signal CHLD, forcing to default. With this patch, comsatd is more careful about child processes, and also will exit more quickly if its first child exits before the select() timeout. For this reason I've also increased the timeout before killing a child to 1 second; unless the child is really hung, this should never be reached. NOTE: This patch applies on top of: mailutils-1.2-comsatd-exec-without-tty-2.patch It will NOT apply cleanly to stock mailutils-1.2. diff -urN mailutils-1.2.orig/comsat/comsat.c mailutils-1.2/comsat/comsat.c --- mailutils-1.2.orig/comsat/comsat.c 2007-06-27 05:07:16.000000000 -0700 +++ mailutils-1.2/comsat/comsat.c 2007-09-21 01:39:30.000000000 -0700 @@ -192,6 +192,20 @@ } void +comsat_parent_sig_chld (int sig) +{ + if (waitpid(-1, NULL, WNOHANG) > 0) + exit (0); /* child is finished, we can exit immediately */ +} + +void +comsat_child_sig_chld (int sig) +{ + while (waitpid(-1, NULL, WNOHANG) > 0) + ; /* reap but ignore */ +} + +void comsat_init () { mu_registrar_record (mu_path_record); @@ -200,7 +214,7 @@ /* Set signal handlers */ signal (SIGTTOU, SIG_IGN); - signal (SIGCHLD, SIG_IGN); + signal (SIGCHLD, comsat_parent_sig_chld); signal (SIGHUP, SIG_IGN); /* Ignore SIGHUP. */ } @@ -392,14 +406,15 @@ if (pid > 0) { struct timeval tv; - tv.tv_sec = 0; - tv.tv_usec = 100000; + tv.tv_sec = 1; + tv.tv_usec = 0; select (0, NULL, NULL, NULL, &tv); - kill (pid, SIGKILL); /* Just in case the child is hung */ + kill (pid, SIGKILL); /* Child has not exited; must be hung */ return 0; } /* Child: do actual I/O */ + signal (SIGCHLD, comsat_child_sig_chld); notify_user (buffer, use_tty ? tty : NULL); exit (0); }