@@ -156,6 +156,7 @@ pid_t child_pid = -1;
156
156
157
157
static volatile sig_atomic_t received_SIGCHLD = 0 ;
158
158
static volatile sig_atomic_t received_signal = -1 ;
159
+ static volatile sig_atomic_t error_in_signalhandler = 0 ;
159
160
160
161
int child_pipefd[3 ][2 ];
161
162
int child_redirfd[3 ];
@@ -192,7 +193,7 @@ struct option const long_opts[] = {
192
193
void warning ( const char *, ...) __attribute__((format (printf, 1 , 2 )));
193
194
void verbose ( const char *, ...) __attribute__((format (printf, 1 , 2 )));
194
195
void 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 )));
196
197
197
198
void warning (const char *format, ...)
198
199
{
@@ -226,6 +227,22 @@ void verbose(const char *format, ...)
226
227
va_end (ap);
227
228
}
228
229
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
+
229
246
void error (int errnum, const char *format, ...)
230
247
{
231
248
// Silently ignore errors that happen while handling other errors.
@@ -674,43 +691,45 @@ void terminate(int sig)
674
691
sigact.sa_handler = SIG_DFL;
675
692
sigact.sa_flags = 0 ;
676
693
if ( sigemptyset (&sigact.sa_mask )!=0 ) {
677
- warning (" could not initialize signal mask" );
694
+ warning_from_signalhandler (" could not initialize signal mask" );
678
695
}
679
696
if ( sigaction (SIGTERM,&sigact,nullptr )!=0 ) {
680
- warning (" could not restore signal handler" );
697
+ warning_from_signalhandler (" could not restore signal handler" );
681
698
}
682
699
if ( sigaction (SIGALRM,&sigact,nullptr )!=0 ) {
683
- warning (" could not restore signal handler" );
700
+ warning_from_signalhandler (" could not restore signal handler" );
684
701
}
685
702
686
703
if ( sig==SIGALRM ) {
687
704
if (runpipe_pid > 0 ) {
688
- warning (" sending SIGUSR1 to runpipe with pid %d " , runpipe_pid );
705
+ warning_from_signalhandler (" sending SIGUSR1 to runpipe" );
689
706
kill (runpipe_pid, SIGUSR1);
690
707
}
691
708
692
709
walllimit_reached |= hard_timelimit;
693
- warning (" timelimit exceeded (hard wall time): aborting command" );
710
+ warning_from_signalhandler (" timelimit exceeded (hard wall time): aborting command" );
694
711
} else {
695
- warning (" received signal %d : aborting command" ,sig );
712
+ warning_from_signalhandler (" received signal: aborting command" );
696
713
}
697
714
698
715
received_signal = sig;
699
716
700
717
/* First try to kill graciously, then hard.
701
718
Don't report an already exited process as error. */
702
- verbose (" sending SIGTERM" );
719
+ verbose_from_signalhandler (" sending SIGTERM" );
703
720
if ( kill (-child_pid,SIGTERM)!=0 && errno!=ESRCH ) {
704
- error (errno," sending SIGTERM to command" );
721
+ error_in_signalhandler = 1 ;
722
+ return ;
705
723
}
706
724
707
725
/* Prefer nanosleep over sleep because of higher resolution and
708
726
it does not interfere with signals. */
709
727
nanosleep (&killdelay,nullptr );
710
728
711
- verbose (" sending SIGKILL" );
729
+ verbose_from_signalhandler (" sending SIGKILL" );
712
730
if ( kill (-child_pid,SIGKILL)!=0 && errno!=ESRCH ) {
713
- error (errno," sending SIGKILL to command" );
731
+ error_in_signalhandler = 1 ;
732
+ return ;
714
733
}
715
734
716
735
/* Wait another while to make sure the process is killed by now. */
@@ -1465,6 +1484,9 @@ int main(int argc, char **argv)
1465
1484
1466
1485
int r = pselect (nfds+1 , &readfds, nullptr , NULL , NULL , &emptymask);
1467
1486
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
+ }
1468
1490
1469
1491
if ( received_SIGCHLD || received_signal == SIGALRM ) {
1470
1492
pid_t pid;
0 commit comments