@@ -156,6 +156,7 @@ pid_t child_pid = -1;
156156
157157static volatile sig_atomic_t received_SIGCHLD = 0 ;
158158static volatile sig_atomic_t received_signal = -1 ;
159+ static volatile sig_atomic_t error_in_signalhandler = 0 ;
159160
160161int child_pipefd[3 ][2 ];
161162int child_redirfd[3 ];
@@ -192,7 +193,7 @@ struct option const long_opts[] = {
192193void warning ( const char *, ...) __attribute__((format (printf, 1 , 2 )));
193194void verbose ( const char *, ...) __attribute__((format (printf, 1 , 2 )));
194195void error (int , const char *, ...) __attribute__((format (printf, 2 , 3 )));
195- void write_meta (const char *, const char *, ...) __attribute__((format (printf, 2 , 3 )));
196+ void write_meta (const char *, const char *, ...) __attribute__((format (printf, 2 , 3 )));
196197
197198void warning (const char *format, ...)
198199{
@@ -226,6 +227,22 @@ void verbose(const char *format, ...)
226227 va_end (ap);
227228}
228229
230+ void verbose_from_signalhandler (const char * msg)
231+ {
232+ if (!be_quiet) {
233+ write (STDERR_FILENO, msg, strlen (msg));
234+ }
235+ }
236+
237+ void warning_from_signalhandler (const char * msg)
238+ {
239+ if (!be_quiet && be_verbose) {
240+ // Do not include timing here, as it wouldn't be safe from a signalhandler.
241+ // TODO: Consider rewriting using clock_gettime in the future.
242+ write (STDERR_FILENO, msg, strlen (msg));
243+ }
244+ }
245+
229246void error (int errnum, const char *format, ...)
230247{
231248 // Silently ignore errors that happen while handling other errors.
@@ -674,43 +691,45 @@ void terminate(int sig)
674691 sigact.sa_handler = SIG_DFL;
675692 sigact.sa_flags = 0 ;
676693 if ( sigemptyset (&sigact.sa_mask )!=0 ) {
677- warning (" could not initialize signal mask" );
694+ warning_from_signalhandler (" could not initialize signal mask" );
678695 }
679696 if ( sigaction (SIGTERM,&sigact,nullptr )!=0 ) {
680- warning (" could not restore signal handler" );
697+ warning_from_signalhandler (" could not restore signal handler" );
681698 }
682699 if ( sigaction (SIGALRM,&sigact,nullptr )!=0 ) {
683- warning (" could not restore signal handler" );
700+ warning_from_signalhandler (" could not restore signal handler" );
684701 }
685702
686703 if ( sig==SIGALRM ) {
687704 if (runpipe_pid > 0 ) {
688- warning (" sending SIGUSR1 to runpipe with pid %d " , runpipe_pid );
705+ warning_from_signalhandler (" sending SIGUSR1 to runpipe" );
689706 kill (runpipe_pid, SIGUSR1);
690707 }
691708
692709 walllimit_reached |= hard_timelimit;
693- warning (" timelimit exceeded (hard wall time): aborting command" );
710+ warning_from_signalhandler (" timelimit exceeded (hard wall time): aborting command" );
694711 } else {
695- warning (" received signal %d : aborting command" ,sig );
712+ warning_from_signalhandler (" received signal: aborting command" );
696713 }
697714
698715 received_signal = sig;
699716
700717 /* First try to kill graciously, then hard.
701718 Don't report an already exited process as error. */
702- verbose (" sending SIGTERM" );
719+ verbose_from_signalhandler (" sending SIGTERM" );
703720 if ( kill (-child_pid,SIGTERM)!=0 && errno!=ESRCH ) {
704- error (errno," sending SIGTERM to command" );
721+ error_in_signalhandler = 1 ;
722+ return ;
705723 }
706724
707725 /* Prefer nanosleep over sleep because of higher resolution and
708726 it does not interfere with signals. */
709727 nanosleep (&killdelay,nullptr );
710728
711- verbose (" sending SIGKILL" );
729+ verbose_from_signalhandler (" sending SIGKILL" );
712730 if ( kill (-child_pid,SIGKILL)!=0 && errno!=ESRCH ) {
713- error (errno," sending SIGKILL to command" );
731+ error_in_signalhandler = 1 ;
732+ return ;
714733 }
715734
716735 /* Wait another while to make sure the process is killed by now. */
@@ -1465,6 +1484,9 @@ int main(int argc, char **argv)
14651484
14661485 int r = pselect (nfds+1 , &readfds, nullptr , NULL , NULL , &emptymask);
14671486 if ( r==-1 && errno!=EINTR ) error (errno," waiting for child data" );
1487+ if (error_in_signalhandler) {
1488+ error (errno, " error in signal handler, exiting" );
1489+ }
14681490
14691491 if ( received_SIGCHLD || received_signal == SIGALRM ) {
14701492 pid_t pid;
0 commit comments