1 /* sig.c - interface for shell signal handlers and signal initialization. */
3 /* Copyright (C) 1994-2015 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"
46 #include "builtins/builtext.h"
48 #if defined (READLINE)
49 # include "bashline.h"
50 # include <readline/readline.h>
54 # include "bashhist.h"
57 extern int last_command_exit_value
;
58 extern int last_command_exit_signal
;
59 extern int return_catch_flag
;
60 extern int running_trap
;
61 extern int loop_level
, continuing
, breaking
, funcnest
;
62 extern int executing_list
;
63 extern int comsub_ignore_return
;
64 extern int parse_and_execute_level
, shell_initialized
;
66 extern int history_lines_this_session
;
68 extern int no_line_editing
;
69 extern int wait_signal_received
;
70 extern int wait_intr_flag
;
71 extern sh_builtin_func_t
*this_shell_builtin
;
73 extern void initialize_siglist ();
75 #if !defined (JOB_CONTROL)
76 extern void initialize_job_signals
__P((void));
79 /* Non-zero after SIGINT. */
80 volatile sig_atomic_t interrupt_state
= 0;
82 /* Non-zero after SIGWINCH */
83 volatile sig_atomic_t sigwinch_received
= 0;
85 /* Non-zero after SIGTERM */
86 volatile sig_atomic_t sigterm_received
= 0;
88 /* Set to the value of any terminating signal received. */
89 volatile sig_atomic_t terminating_signal
= 0;
91 /* The environment at the top-level R-E loop. We use this in
92 the case of error return. */
95 #if defined (JOB_CONTROL) || defined (HAVE_POSIX_SIGNALS)
96 /* The signal masks that this shell runs with. */
97 sigset_t top_level_mask
;
98 #endif /* JOB_CONTROL */
100 /* When non-zero, we throw_to_top_level (). */
101 int interrupt_immediately
= 0;
103 /* When non-zero, we call the terminating signal handler immediately. */
104 int terminate_immediately
= 0;
106 #if defined (SIGWINCH)
107 static SigHandler
*old_winch
= (SigHandler
*)SIG_DFL
;
110 static void initialize_shell_signals
__P((void));
113 initialize_signals (reinit
)
116 initialize_shell_signals ();
117 initialize_job_signals ();
118 #if !defined (HAVE_SYS_SIGLIST) && !defined (HAVE_UNDER_SYS_SIGLIST) && !defined (HAVE_STRSIGNAL)
120 initialize_siglist ();
121 #endif /* !HAVE_SYS_SIGLIST && !HAVE_UNDER_SYS_SIGLIST && !HAVE_STRSIGNAL */
124 /* A structure describing a signal that terminates the shell if not
125 caught. The orig_handler member is present so children can reset
126 these signals back to their original handlers. */
129 SigHandler
*orig_handler
;
133 #define NULL_HANDLER (SigHandler *)SIG_DFL
135 /* The list of signals that would terminate the shell if not caught.
136 We catch them, but just so that we can write the history file,
138 static struct termsig terminating_signals
[] = {
140 { SIGHUP
, NULL_HANDLER
, 0 },
144 { SIGINT
, NULL_HANDLER
, 0 },
148 { SIGILL
, NULL_HANDLER
, 0 },
152 { SIGTRAP
, NULL_HANDLER
, 0 },
156 { SIGIOT
, NULL_HANDLER
, 0 },
160 { SIGDANGER
, NULL_HANDLER
, 0 },
164 { SIGEMT
, NULL_HANDLER
, 0 },
168 { SIGFPE
, NULL_HANDLER
, 0 },
172 { SIGBUS
, NULL_HANDLER
, 0 },
176 { SIGSEGV
, NULL_HANDLER
, 0 },
180 { SIGSYS
, NULL_HANDLER
, 0 },
184 { SIGPIPE
, NULL_HANDLER
, 0 },
188 { SIGALRM
, NULL_HANDLER
, 0 },
192 { SIGTERM
, NULL_HANDLER
, 0 },
196 { SIGXCPU
, NULL_HANDLER
, 0 },
200 { SIGXFSZ
, NULL_HANDLER
, 0 },
204 { SIGVTALRM
, NULL_HANDLER
, 0 },
209 { SIGPROF
, NULL_HANDLER
, 0 },
214 { SIGLOST
, NULL_HANDLER
, 0 },
218 { SIGUSR1
, NULL_HANDLER
, 0 },
222 { SIGUSR2
, NULL_HANDLER
, 0 },
226 #define TERMSIGS_LENGTH (sizeof (terminating_signals) / sizeof (struct termsig))
228 #define XSIG(x) (terminating_signals[x].signum)
229 #define XHANDLER(x) (terminating_signals[x].orig_handler)
230 #define XSAFLAGS(x) (terminating_signals[x].orig_flags)
232 static int termsigs_initialized
= 0;
234 /* Initialize signals that will terminate the shell to do some
235 unwind protection. For non-interactive shells, we only call
236 this when a trap is defined for EXIT (0) or when trap is run
237 to display signal dispositions. */
239 initialize_terminating_signals ()
242 #if defined (HAVE_POSIX_SIGNALS)
243 struct sigaction act
, oact
;
246 if (termsigs_initialized
)
249 /* The following code is to avoid an expensive call to
250 set_signal_handler () for each terminating_signals. Fortunately,
251 this is possible in Posix. Unfortunately, we have to call signal ()
252 on non-Posix systems for each signal in terminating_signals. */
253 #if defined (HAVE_POSIX_SIGNALS)
254 act
.sa_handler
= termsig_sighandler
;
256 sigemptyset (&act
.sa_mask
);
257 sigemptyset (&oact
.sa_mask
);
258 for (i
= 0; i
< TERMSIGS_LENGTH
; i
++)
259 sigaddset (&act
.sa_mask
, XSIG (i
));
260 for (i
= 0; i
< TERMSIGS_LENGTH
; i
++)
262 /* If we've already trapped it, don't do anything. */
263 if (signal_is_trapped (XSIG (i
)))
266 sigaction (XSIG (i
), &act
, &oact
);
267 XHANDLER(i
) = oact
.sa_handler
;
268 XSAFLAGS(i
) = oact
.sa_flags
;
269 /* Don't do anything with signals that are ignored at shell entry
270 if the shell is not interactive. */
271 /* XXX - should we do this for interactive shells, too? */
272 if (interactive_shell
== 0 && XHANDLER (i
) == SIG_IGN
)
274 sigaction (XSIG (i
), &oact
, &act
);
275 set_signal_hard_ignored (XSIG (i
));
277 #if defined (SIGPROF) && !defined (_MINIX)
278 if (XSIG (i
) == SIGPROF
&& XHANDLER (i
) != SIG_DFL
&& XHANDLER (i
) != SIG_IGN
)
279 sigaction (XSIG (i
), &oact
, (struct sigaction
*)NULL
);
280 #endif /* SIGPROF && !_MINIX */
283 #else /* !HAVE_POSIX_SIGNALS */
285 for (i
= 0; i
< TERMSIGS_LENGTH
; i
++)
287 /* If we've already trapped it, don't do anything. */
288 if (signal_is_trapped (XSIG (i
)))
291 XHANDLER(i
) = signal (XSIG (i
), termsig_sighandler
);
293 /* Don't do anything with signals that are ignored at shell entry
294 if the shell is not interactive. */
295 /* XXX - should we do this for interactive shells, too? */
296 if (interactive_shell
== 0 && XHANDLER (i
) == SIG_IGN
)
298 signal (XSIG (i
), SIG_IGN
);
299 set_signal_hard_ignored (XSIG (i
));
302 if (XSIG (i
) == SIGPROF
&& XHANDLER (i
) != SIG_DFL
&& XHANDLER (i
) != SIG_IGN
)
303 signal (XSIG (i
), XHANDLER (i
));
307 #endif /* !HAVE_POSIX_SIGNALS */
309 termsigs_initialized
= 1;
313 initialize_shell_signals ()
316 initialize_terminating_signals ();
318 #if defined (JOB_CONTROL) || defined (HAVE_POSIX_SIGNALS)
319 /* All shells use the signal mask they inherit, and pass it along
320 to child processes. Children will never block SIGCHLD, though. */
321 sigemptyset (&top_level_mask
);
322 sigprocmask (SIG_BLOCK
, (sigset_t
*)NULL
, &top_level_mask
);
323 # if defined (SIGCHLD)
324 sigdelset (&top_level_mask
, SIGCHLD
);
326 #endif /* JOB_CONTROL || HAVE_POSIX_SIGNALS */
328 /* And, some signals that are specifically ignored by the shell. */
329 set_signal_handler (SIGQUIT
, SIG_IGN
);
333 set_signal_handler (SIGINT
, sigint_sighandler
);
334 get_original_signal (SIGTERM
);
335 if (signal_is_hard_ignored (SIGTERM
) == 0)
336 set_signal_handler (SIGTERM
, sigterm_sighandler
);
337 set_sigwinch_handler ();
342 reset_terminating_signals ()
345 #if defined (HAVE_POSIX_SIGNALS)
346 struct sigaction act
;
349 if (termsigs_initialized
== 0)
352 #if defined (HAVE_POSIX_SIGNALS)
354 sigemptyset (&act
.sa_mask
);
355 for (i
= 0; i
< TERMSIGS_LENGTH
; i
++)
357 /* Skip a signal if it's trapped or handled specially, because the
358 trap code will restore the correct value. */
359 if (signal_is_trapped (XSIG (i
)) || signal_is_special (XSIG (i
)))
362 act
.sa_handler
= XHANDLER (i
);
363 act
.sa_flags
= XSAFLAGS (i
);
364 sigaction (XSIG (i
), &act
, (struct sigaction
*) NULL
);
366 #else /* !HAVE_POSIX_SIGNALS */
367 for (i
= 0; i
< TERMSIGS_LENGTH
; i
++)
369 if (signal_is_trapped (XSIG (i
)) || signal_is_special (XSIG (i
)))
372 signal (XSIG (i
), XHANDLER (i
));
374 #endif /* !HAVE_POSIX_SIGNALS */
376 termsigs_initialized
= 0;
381 /* Run some of the cleanups that should be performed when we run
382 jump_to_top_level from a builtin command context. XXX - might want to
383 also call reset_parser here. */
387 /* Clean up string parser environment. */
388 while (parse_and_execute_level
)
389 parse_and_execute_cleanup ();
391 #if defined (PROCESS_SUBSTITUTION)
393 #endif /* PROCESS_SUBSTITUTION */
395 run_unwind_protects ();
396 loop_level
= continuing
= breaking
= funcnest
= 0;
397 executing_list
= comsub_ignore_return
= return_catch_flag
= wait_intr_flag
= 0;
400 /* What to do when we've been interrupted, and it is safe to handle it. */
402 throw_to_top_level ()
404 int print_newline
= 0;
408 if (last_command_exit_value
< 128)
409 last_command_exit_value
= 128 + SIGINT
;
417 last_command_exit_signal
= (last_command_exit_value
> 128) ?
418 (last_command_exit_value
- 128) : 0;
419 last_command_exit_value
|= 128;
421 /* Run any traps set on SIGINT, mostly for interactive shells */
422 if (signal_is_trapped (SIGINT
))
423 run_interrupt_trap (1);
425 /* Clean up string parser environment. */
426 while (parse_and_execute_level
)
427 parse_and_execute_cleanup ();
429 if (running_trap
> 0)
430 run_trap_cleanup (running_trap
- 1);
432 #if defined (JOB_CONTROL)
433 give_terminal_to (shell_pgrp
, 0);
434 #endif /* JOB_CONTROL */
436 #if defined (JOB_CONTROL) || defined (HAVE_POSIX_SIGNALS)
437 /* This needs to stay because jobs.c:make_child() uses it without resetting
439 sigprocmask (SIG_SETMASK
, &top_level_mask
, (sigset_t
*)NULL
);
444 #if defined (READLINE)
447 #endif /* READLINE */
449 #if defined (PROCESS_SUBSTITUTION)
451 #endif /* PROCESS_SUBSTITUTION */
453 run_unwind_protects ();
454 loop_level
= continuing
= breaking
= funcnest
= 0;
455 executing_list
= comsub_ignore_return
= return_catch_flag
= wait_intr_flag
= 0;
457 if (interactive
&& print_newline
)
460 fprintf (stderr
, "\n");
464 /* An interrupted `wait' command in a script does not exit the script. */
465 if (interactive
|| (interactive_shell
&& !shell_initialized
) ||
466 (print_newline
&& signal_is_trapped (SIGINT
)))
467 jump_to_top_level (DISCARD
);
469 jump_to_top_level (EXITPROG
);
472 /* This is just here to isolate the longjmp calls. */
474 jump_to_top_level (value
)
477 sh_longjmp (top_level
, value
);
481 termsig_sighandler (sig
)
484 /* If we get called twice with the same signal before handling it,
485 terminate right away. */
523 sig
== terminating_signal
)
524 terminate_immediately
= 1;
526 terminating_signal
= sig
;
528 /* XXX - should this also trigger when interrupt_immediately is set? */
529 if (terminate_immediately
)
531 #if defined (HISTORY)
532 /* XXX - will inhibit history file being written */
533 # if defined (READLINE)
534 if (interactive_shell
== 0 || interactive
== 0 || (sig
!= SIGHUP
&& sig
!= SIGTERM
) || no_line_editing
|| (RL_ISSTATE (RL_STATE_READCMD
) == 0))
536 history_lines_this_session
= 0;
538 terminate_immediately
= 0;
539 termsig_handler (sig
);
542 #if defined (READLINE)
543 /* Set the event hook so readline will call it after the signal handlers
544 finish executing, so if this interrupted character input we can get
545 quick response. If readline is active or has modified the terminal we
546 need to set this no matter what the signal is, though the check for
547 RL_STATE_TERMPREPPED is possibly redundant. */
548 if (RL_ISSTATE (RL_STATE_SIGHANDLER
) || RL_ISSTATE (RL_STATE_TERMPREPPED
))
549 bashline_set_event_hook ();
556 termsig_handler (sig
)
559 static int handling_termsig
= 0;
561 /* Simple semaphore to keep this function from being executed multiple
562 times. Since we no longer are running as a signal handler, we don't
563 block multiple occurrences of the terminating signals while running. */
564 if (handling_termsig
)
566 handling_termsig
= 1;
567 terminating_signal
= 0; /* keep macro from re-testing true. */
569 /* I don't believe this condition ever tests true. */
570 if (sig
== SIGINT
&& signal_is_trapped (SIGINT
))
571 run_interrupt_trap (0);
573 #if defined (HISTORY)
574 /* If we don't do something like this, the history will not be saved when
575 an interactive shell is running in a terminal window that gets closed
576 with the `close' button. We can't test for RL_STATE_READCMD because
577 readline no longer handles SIGTERM synchronously. */
578 if (interactive_shell
&& interactive
&& (sig
== SIGHUP
|| sig
== SIGTERM
) && remember_on_history
)
579 maybe_save_shell_history ();
582 if (this_shell_builtin
== read_builtin
)
585 #if defined (JOB_CONTROL)
586 if (sig
== SIGHUP
&& (interactive
|| (subshell_environment
& (SUBSHELL_COMSUB
|SUBSHELL_PROCSUB
))))
588 if ((subshell_environment
& (SUBSHELL_COMSUB
|SUBSHELL_PROCSUB
)) == 0)
590 #endif /* JOB_CONTROL */
592 #if defined (PROCESS_SUBSTITUTION)
594 #endif /* PROCESS_SUBSTITUTION */
596 /* Reset execution context */
597 loop_level
= continuing
= breaking
= funcnest
= 0;
598 executing_list
= comsub_ignore_return
= return_catch_flag
= wait_intr_flag
= 0;
600 run_exit_trap (); /* XXX - run exit trap possibly in signal context? */
601 set_signal_handler (sig
, SIG_DFL
);
602 kill (getpid (), sig
);
605 /* What we really do when SIGINT occurs. */
607 sigint_sighandler (sig
)
610 #if defined (MUST_REINSTALL_SIGHANDLERS)
611 signal (sig
, sigint_sighandler
);
614 /* interrupt_state needs to be set for the stack of interrupts to work
615 right. Should it be set unconditionally? */
616 if (interrupt_state
== 0)
619 /* We will get here in interactive shells with job control active; allow
620 an interactive wait to be interrupted. wait_intr_flag is only set during
621 the execution of the wait builtin and when wait_intr_buf is valid. */
624 last_command_exit_value
= 128 + sig
;
625 wait_signal_received
= sig
;
629 if (interrupt_immediately
)
631 interrupt_immediately
= 0;
632 last_command_exit_value
= 128 + sig
;
633 throw_to_top_level ();
635 #if defined (READLINE)
636 /* Set the event hook so readline will call it after the signal handlers
637 finish executing, so if this interrupted character input we can get
639 else if (RL_ISSTATE (RL_STATE_SIGHANDLER
))
640 bashline_set_event_hook ();
646 #if defined (SIGWINCH)
648 sigwinch_sighandler (sig
)
651 #if defined (MUST_REINSTALL_SIGHANDLERS)
652 set_signal_handler (SIGWINCH
, sigwinch_sighandler
);
653 #endif /* MUST_REINSTALL_SIGHANDLERS */
654 sigwinch_received
= 1;
657 #endif /* SIGWINCH */
660 set_sigwinch_handler ()
662 #if defined (SIGWINCH)
663 old_winch
= set_signal_handler (SIGWINCH
, sigwinch_sighandler
);
668 unset_sigwinch_handler ()
670 #if defined (SIGWINCH)
671 set_signal_handler (SIGWINCH
, old_winch
);
676 sigterm_sighandler (sig
)
679 sigterm_received
= 1; /* XXX - counter? */
683 /* Signal functions used by the rest of the code. */
684 #if !defined (HAVE_POSIX_SIGNALS)
686 /* Perform OPERATION on NEWSET, perhaps leaving information in OLDSET. */
687 sigprocmask (operation
, newset
, oldset
)
688 int operation
, *newset
, *oldset
;
700 old
= sigblock (new);
704 old
= sigsetmask (new);
708 internal_error (_("sigprocmask: %d: invalid operation"), operation
);
717 #if !defined (SA_INTERRUPT)
718 # define SA_INTERRUPT 0
721 #if !defined (SA_RESTART)
722 # define SA_RESTART 0
726 set_signal_handler (sig
, handler
)
730 struct sigaction act
, oact
;
732 act
.sa_handler
= handler
;
736 /* We don't want a child death to interrupt interruptible system calls, even
737 if we take the time to reap children */
738 #if defined (SIGCHLD)
740 act
.sa_flags
|= SA_RESTART
; /* XXX */
742 /* If we're installing a SIGTERM handler for interactive shells, we want
743 it to be as close to SIG_IGN as possible. */
744 if (sig
== SIGTERM
&& handler
== sigterm_sighandler
)
745 act
.sa_flags
|= SA_RESTART
; /* XXX */
747 sigemptyset (&act
.sa_mask
);
748 sigemptyset (&oact
.sa_mask
);
749 if (sigaction (sig
, &act
, &oact
) == 0)
750 return (oact
.sa_handler
);
754 #endif /* HAVE_POSIX_SIGNALS */