1 /* sig.c - interface for shell signal handlers and signal initialization. */
3 /* Copyright (C) 1994-2009 Free Software Foundation, Inc.
5 This file is part of GNU Bash, the Bourne Again SHell.
7 Bash is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
12 Bash is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with Bash. If not, see <http://www.gnu.org/licenses/>.
23 #include "bashtypes.h"
25 #if defined (HAVE_UNISTD_H)
27 # include <sys/types.h>
38 #if defined (JOB_CONTROL)
40 #endif /* JOB_CONTROL */
45 #include "builtins/common.h"
47 #if defined (READLINE)
48 # include "bashline.h"
52 # include "bashhist.h"
55 extern int last_command_exit_value
;
56 extern int last_command_exit_signal
;
57 extern int return_catch_flag
;
58 extern int loop_level
, continuing
, breaking
;
59 extern int executing_list
;
60 extern int comsub_ignore_return
;
61 extern int parse_and_execute_level
, shell_initialized
;
63 /* Non-zero after SIGINT. */
64 volatile int interrupt_state
= 0;
66 /* Non-zero after SIGWINCH */
67 volatile int sigwinch_received
= 0;
69 /* Set to the value of any terminating signal received. */
70 volatile int terminating_signal
= 0;
72 /* The environment at the top-level R-E loop. We use this in
73 the case of error return. */
76 #if defined (JOB_CONTROL) || defined (HAVE_POSIX_SIGNALS)
77 /* The signal masks that this shell runs with. */
78 sigset_t top_level_mask
;
79 #endif /* JOB_CONTROL */
81 /* When non-zero, we throw_to_top_level (). */
82 int interrupt_immediately
= 0;
84 /* When non-zero, we call the terminating signal handler immediately. */
85 int terminate_immediately
= 0;
87 #if defined (SIGWINCH)
88 static SigHandler
*old_winch
= (SigHandler
*)SIG_DFL
;
91 static void initialize_shell_signals
__P((void));
94 initialize_signals (reinit
)
97 initialize_shell_signals ();
98 initialize_job_signals ();
99 #if !defined (HAVE_SYS_SIGLIST) && !defined (HAVE_UNDER_SYS_SIGLIST) && !defined (HAVE_STRSIGNAL)
101 initialize_siglist ();
102 #endif /* !HAVE_SYS_SIGLIST && !HAVE_UNDER_SYS_SIGLIST && !HAVE_STRSIGNAL */
105 /* A structure describing a signal that terminates the shell if not
106 caught. The orig_handler member is present so children can reset
107 these signals back to their original handlers. */
110 SigHandler
*orig_handler
;
114 #define NULL_HANDLER (SigHandler *)SIG_DFL
116 /* The list of signals that would terminate the shell if not caught.
117 We catch them, but just so that we can write the history file,
119 static struct termsig terminating_signals
[] = {
121 { SIGHUP
, NULL_HANDLER
, 0 },
125 { SIGINT
, NULL_HANDLER
, 0 },
129 { SIGILL
, NULL_HANDLER
, 0 },
133 { SIGTRAP
, NULL_HANDLER
, 0 },
137 { SIGIOT
, NULL_HANDLER
, 0 },
141 { SIGDANGER
, NULL_HANDLER
, 0 },
145 { SIGEMT
, NULL_HANDLER
, 0 },
149 { SIGFPE
, NULL_HANDLER
, 0 },
153 { SIGBUS
, NULL_HANDLER
, 0 },
157 { SIGSEGV
, NULL_HANDLER
, 0 },
161 { SIGSYS
, NULL_HANDLER
, 0 },
165 { SIGPIPE
, NULL_HANDLER
, 0 },
169 { SIGALRM
, NULL_HANDLER
, 0 },
173 { SIGTERM
, NULL_HANDLER
, 0 },
177 { SIGXCPU
, NULL_HANDLER
, 0 },
181 { SIGXFSZ
, NULL_HANDLER
, 0 },
185 { SIGVTALRM
, NULL_HANDLER
, 0 },
190 { SIGPROF
, NULL_HANDLER
, 0 },
195 { SIGLOST
, NULL_HANDLER
, 0 },
199 { SIGUSR1
, NULL_HANDLER
, 0 },
203 { SIGUSR2
, NULL_HANDLER
, 0 },
207 #define TERMSIGS_LENGTH (sizeof (terminating_signals) / sizeof (struct termsig))
209 #define XSIG(x) (terminating_signals[x].signum)
210 #define XHANDLER(x) (terminating_signals[x].orig_handler)
211 #define XSAFLAGS(x) (terminating_signals[x].orig_flags)
213 static int termsigs_initialized
= 0;
215 /* Initialize signals that will terminate the shell to do some
216 unwind protection. For non-interactive shells, we only call
217 this when a trap is defined for EXIT (0). */
219 initialize_terminating_signals ()
222 #if defined (HAVE_POSIX_SIGNALS)
223 struct sigaction act
, oact
;
226 if (termsigs_initialized
)
229 /* The following code is to avoid an expensive call to
230 set_signal_handler () for each terminating_signals. Fortunately,
231 this is possible in Posix. Unfortunately, we have to call signal ()
232 on non-Posix systems for each signal in terminating_signals. */
233 #if defined (HAVE_POSIX_SIGNALS)
234 act
.sa_handler
= termsig_sighandler
;
236 sigemptyset (&act
.sa_mask
);
237 sigemptyset (&oact
.sa_mask
);
238 for (i
= 0; i
< TERMSIGS_LENGTH
; i
++)
239 sigaddset (&act
.sa_mask
, XSIG (i
));
240 for (i
= 0; i
< TERMSIGS_LENGTH
; i
++)
242 /* If we've already trapped it, don't do anything. */
243 if (signal_is_trapped (XSIG (i
)))
246 sigaction (XSIG (i
), &act
, &oact
);
247 XHANDLER(i
) = oact
.sa_handler
;
248 XSAFLAGS(i
) = oact
.sa_flags
;
249 /* Don't do anything with signals that are ignored at shell entry
250 if the shell is not interactive. */
251 if (!interactive_shell
&& XHANDLER (i
) == SIG_IGN
)
253 sigaction (XSIG (i
), &oact
, &act
);
254 set_signal_ignored (XSIG (i
));
256 #if defined (SIGPROF) && !defined (_MINIX)
257 if (XSIG (i
) == SIGPROF
&& XHANDLER (i
) != SIG_DFL
&& XHANDLER (i
) != SIG_IGN
)
258 sigaction (XSIG (i
), &oact
, (struct sigaction
*)NULL
);
259 #endif /* SIGPROF && !_MINIX */
262 #else /* !HAVE_POSIX_SIGNALS */
264 for (i
= 0; i
< TERMSIGS_LENGTH
; i
++)
266 /* If we've already trapped it, don't do anything. */
267 if (signal_is_trapped (XSIG (i
)))
270 XHANDLER(i
) = signal (XSIG (i
), termsig_sighandler
);
272 /* Don't do anything with signals that are ignored at shell entry
273 if the shell is not interactive. */
274 if (!interactive_shell
&& XHANDLER (i
) == SIG_IGN
)
276 signal (XSIG (i
), SIG_IGN
);
277 set_signal_ignored (XSIG (i
));
280 if (XSIG (i
) == SIGPROF
&& XHANDLER (i
) != SIG_DFL
&& XHANDLER (i
) != SIG_IGN
)
281 signal (XSIG (i
), XHANDLER (i
));
285 #endif /* !HAVE_POSIX_SIGNALS */
287 termsigs_initialized
= 1;
291 initialize_shell_signals ()
294 initialize_terminating_signals ();
296 #if defined (JOB_CONTROL) || defined (HAVE_POSIX_SIGNALS)
297 /* All shells use the signal mask they inherit, and pass it along
298 to child processes. Children will never block SIGCHLD, though. */
299 sigemptyset (&top_level_mask
);
300 sigprocmask (SIG_BLOCK
, (sigset_t
*)NULL
, &top_level_mask
);
301 # if defined (SIGCHLD)
302 sigdelset (&top_level_mask
, SIGCHLD
);
304 #endif /* JOB_CONTROL || HAVE_POSIX_SIGNALS */
306 /* And, some signals that are specifically ignored by the shell. */
307 set_signal_handler (SIGQUIT
, SIG_IGN
);
311 set_signal_handler (SIGINT
, sigint_sighandler
);
312 set_signal_handler (SIGTERM
, SIG_IGN
);
313 set_sigwinch_handler ();
318 reset_terminating_signals ()
321 #if defined (HAVE_POSIX_SIGNALS)
322 struct sigaction act
;
325 if (termsigs_initialized
== 0)
328 #if defined (HAVE_POSIX_SIGNALS)
330 sigemptyset (&act
.sa_mask
);
331 for (i
= 0; i
< TERMSIGS_LENGTH
; i
++)
333 /* Skip a signal if it's trapped or handled specially, because the
334 trap code will restore the correct value. */
335 if (signal_is_trapped (XSIG (i
)) || signal_is_special (XSIG (i
)))
338 act
.sa_handler
= XHANDLER (i
);
339 act
.sa_flags
= XSAFLAGS (i
);
340 sigaction (XSIG (i
), &act
, (struct sigaction
*) NULL
);
342 #else /* !HAVE_POSIX_SIGNALS */
343 for (i
= 0; i
< TERMSIGS_LENGTH
; i
++)
345 if (signal_is_trapped (XSIG (i
)) || signal_is_special (XSIG (i
)))
348 signal (XSIG (i
), XHANDLER (i
));
350 #endif /* !HAVE_POSIX_SIGNALS */
355 /* Run some of the cleanups that should be performed when we run
356 jump_to_top_level from a builtin command context. XXX - might want to
357 also call reset_parser here. */
361 /* Clean up string parser environment. */
362 while (parse_and_execute_level
)
363 parse_and_execute_cleanup ();
365 #if defined (PROCESS_SUBSTITUTION)
367 #endif /* PROCESS_SUBSTITUTION */
369 run_unwind_protects ();
370 loop_level
= continuing
= breaking
= 0;
371 executing_list
= comsub_ignore_return
= return_catch_flag
= 0;
374 /* What to do when we've been interrupted, and it is safe to handle it. */
376 throw_to_top_level ()
378 int print_newline
= 0;
389 last_command_exit_signal
= (last_command_exit_value
> 128) ?
390 (last_command_exit_value
- 128) : 0;
391 last_command_exit_value
|= 128;
393 /* Run any traps set on SIGINT. */
394 run_interrupt_trap ();
396 /* Clean up string parser environment. */
397 while (parse_and_execute_level
)
398 parse_and_execute_cleanup ();
400 #if defined (JOB_CONTROL)
401 give_terminal_to (shell_pgrp
, 0);
402 #endif /* JOB_CONTROL */
404 #if defined (JOB_CONTROL) || defined (HAVE_POSIX_SIGNALS)
405 /* This should not be necessary on systems using sigsetjmp/siglongjmp. */
406 sigprocmask (SIG_SETMASK
, &top_level_mask
, (sigset_t
*)NULL
);
411 #if defined (READLINE)
414 #endif /* READLINE */
416 #if defined (PROCESS_SUBSTITUTION)
418 #endif /* PROCESS_SUBSTITUTION */
420 run_unwind_protects ();
421 loop_level
= continuing
= breaking
= 0;
422 executing_list
= comsub_ignore_return
= return_catch_flag
= 0;
424 if (interactive
&& print_newline
)
427 fprintf (stderr
, "\n");
431 /* An interrupted `wait' command in a script does not exit the script. */
432 if (interactive
|| (interactive_shell
&& !shell_initialized
) ||
433 (print_newline
&& signal_is_trapped (SIGINT
)))
434 jump_to_top_level (DISCARD
);
436 jump_to_top_level (EXITPROG
);
439 /* This is just here to isolate the longjmp calls. */
441 jump_to_top_level (value
)
444 longjmp (top_level
, value
);
448 termsig_sighandler (sig
)
451 /* If we get called twice with the same signal before handling it,
452 terminate right away. */
490 sig
== terminating_signal
)
491 terminate_immediately
= 1;
493 terminating_signal
= sig
;
495 /* XXX - should this also trigger when interrupt_immediately is set? */
496 if (terminate_immediately
)
498 terminate_immediately
= 0;
499 termsig_handler (sig
);
506 termsig_handler (sig
)
509 static int handling_termsig
= 0;
511 /* Simple semaphore to keep this function from being executed multiple
512 times. Since we no longer are running as a signal handler, we don't
513 block multiple occurrences of the terminating signals while running. */
514 if (handling_termsig
)
516 handling_termsig
= 1;
517 terminating_signal
= 0; /* keep macro from re-testing true. */
519 /* I don't believe this condition ever tests true. */
520 if (sig
== SIGINT
&& signal_is_trapped (SIGINT
))
521 run_interrupt_trap ();
523 #if defined (HISTORY)
524 if (interactive_shell
&& sig
!= SIGABRT
)
525 maybe_save_shell_history ();
528 #if defined (JOB_CONTROL)
529 if (interactive
&& sig
== SIGHUP
)
532 #endif /* JOB_CONTROL */
534 #if defined (PROCESS_SUBSTITUTION)
536 #endif /* PROCESS_SUBSTITUTION */
538 /* Reset execution context */
539 loop_level
= continuing
= breaking
= 0;
540 executing_list
= comsub_ignore_return
= return_catch_flag
= 0;
543 set_signal_handler (sig
, SIG_DFL
);
544 kill (getpid (), sig
);
547 /* What we really do when SIGINT occurs. */
549 sigint_sighandler (sig
)
552 #if defined (MUST_REINSTALL_SIGHANDLERS)
553 signal (sig
, sigint_sighandler
);
556 /* interrupt_state needs to be set for the stack of interrupts to work
557 right. Should it be set unconditionally? */
558 if (interrupt_state
== 0)
561 if (interrupt_immediately
)
563 interrupt_immediately
= 0;
564 throw_to_top_level ();
570 #if defined (SIGWINCH)
572 sigwinch_sighandler (sig
)
575 #if defined (MUST_REINSTALL_SIGHANDLERS)
576 set_signal_handler (SIGWINCH
, sigwinch_sighandler
);
577 #endif /* MUST_REINSTALL_SIGHANDLERS */
578 sigwinch_received
= 1;
581 #endif /* SIGWINCH */
584 set_sigwinch_handler ()
586 #if defined (SIGWINCH)
587 old_winch
= set_signal_handler (SIGWINCH
, sigwinch_sighandler
);
592 unset_sigwinch_handler ()
594 #if defined (SIGWINCH)
595 set_signal_handler (SIGWINCH
, old_winch
);
599 /* Signal functions used by the rest of the code. */
600 #if !defined (HAVE_POSIX_SIGNALS)
602 #if defined (JOB_CONTROL)
603 /* Perform OPERATION on NEWSET, perhaps leaving information in OLDSET. */
604 sigprocmask (operation
, newset
, oldset
)
605 int operation
, *newset
, *oldset
;
617 old
= sigblock (new);
625 internal_error (_("sigprocmask: %d: invalid operation"), operation
);
631 #endif /* JOB_CONTROL */
635 #if !defined (SA_INTERRUPT)
636 # define SA_INTERRUPT 0
639 #if !defined (SA_RESTART)
640 # define SA_RESTART 0
644 set_signal_handler (sig
, handler
)
648 struct sigaction act
, oact
;
650 act
.sa_handler
= handler
;
654 act
.sa_flags
|= SA_INTERRUPT
; /* XXX */
656 act
.sa_flags
|= SA_RESTART
; /* XXX */
658 sigemptyset (&act
.sa_mask
);
659 sigemptyset (&oact
.sa_mask
);
660 sigaction (sig
, &act
, &oact
);
661 return (oact
.sa_handler
);
663 #endif /* HAVE_POSIX_SIGNALS */