1 /* sig.c - interface for shell signal handlers and signal initialization. */
3 /* Copyright (C) 1994-2010 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"
49 # include <readline/readline.h>
53 # include "bashhist.h"
56 extern int last_command_exit_value;
57 extern int last_command_exit_signal;
58 extern int return_catch_flag;
59 extern int loop_level, continuing, breaking, funcnest;
60 extern int executing_list;
61 extern int comsub_ignore_return;
62 extern int parse_and_execute_level, shell_initialized;
64 extern int history_lines_this_session;
66 extern int no_line_editing;
68 extern void initialize_siglist ();
70 /* Non-zero after SIGINT. */
71 volatile int interrupt_state = 0;
73 /* Non-zero after SIGWINCH */
74 volatile int sigwinch_received = 0;
76 /* Set to the value of any terminating signal received. */
77 volatile int terminating_signal = 0;
79 /* The environment at the top-level R-E loop. We use this in
80 the case of error return. */
83 #if defined (JOB_CONTROL) || defined (HAVE_POSIX_SIGNALS)
84 /* The signal masks that this shell runs with. */
85 sigset_t top_level_mask;
86 #endif /* JOB_CONTROL */
88 /* When non-zero, we throw_to_top_level (). */
89 int interrupt_immediately = 0;
91 /* When non-zero, we call the terminating signal handler immediately. */
92 int terminate_immediately = 0;
94 #if defined (SIGWINCH)
95 static SigHandler *old_winch = (SigHandler *)SIG_DFL;
98 static void initialize_shell_signals __P((void));
101 initialize_signals (reinit)
104 initialize_shell_signals ();
105 initialize_job_signals ();
106 #if !defined (HAVE_SYS_SIGLIST) && !defined (HAVE_UNDER_SYS_SIGLIST) && !defined (HAVE_STRSIGNAL)
108 initialize_siglist ();
109 #endif /* !HAVE_SYS_SIGLIST && !HAVE_UNDER_SYS_SIGLIST && !HAVE_STRSIGNAL */
112 /* A structure describing a signal that terminates the shell if not
113 caught. The orig_handler member is present so children can reset
114 these signals back to their original handlers. */
117 SigHandler *orig_handler;
121 #define NULL_HANDLER (SigHandler *)SIG_DFL
123 /* The list of signals that would terminate the shell if not caught.
124 We catch them, but just so that we can write the history file,
126 static struct termsig terminating_signals[] = {
128 { SIGHUP, NULL_HANDLER, 0 },
132 { SIGINT, NULL_HANDLER, 0 },
136 { SIGILL, NULL_HANDLER, 0 },
140 { SIGTRAP, NULL_HANDLER, 0 },
144 { SIGIOT, NULL_HANDLER, 0 },
148 { SIGDANGER, NULL_HANDLER, 0 },
152 { SIGEMT, NULL_HANDLER, 0 },
156 { SIGFPE, NULL_HANDLER, 0 },
160 { SIGBUS, NULL_HANDLER, 0 },
164 { SIGSEGV, NULL_HANDLER, 0 },
168 { SIGSYS, NULL_HANDLER, 0 },
172 { SIGPIPE, NULL_HANDLER, 0 },
176 { SIGALRM, NULL_HANDLER, 0 },
180 { SIGTERM, NULL_HANDLER, 0 },
184 { SIGXCPU, NULL_HANDLER, 0 },
188 { SIGXFSZ, NULL_HANDLER, 0 },
192 { SIGVTALRM, NULL_HANDLER, 0 },
197 { SIGPROF, NULL_HANDLER, 0 },
202 { SIGLOST, NULL_HANDLER, 0 },
206 { SIGUSR1, NULL_HANDLER, 0 },
210 { SIGUSR2, NULL_HANDLER, 0 },
214 #define TERMSIGS_LENGTH (sizeof (terminating_signals) / sizeof (struct termsig))
216 #define XSIG(x) (terminating_signals[x].signum)
217 #define XHANDLER(x) (terminating_signals[x].orig_handler)
218 #define XSAFLAGS(x) (terminating_signals[x].orig_flags)
220 static int termsigs_initialized = 0;
222 /* Initialize signals that will terminate the shell to do some
223 unwind protection. For non-interactive shells, we only call
224 this when a trap is defined for EXIT (0) or when trap is run
225 to display signal dispositions. */
227 initialize_terminating_signals ()
230 #if defined (HAVE_POSIX_SIGNALS)
231 struct sigaction act, oact;
234 if (termsigs_initialized)
237 /* The following code is to avoid an expensive call to
238 set_signal_handler () for each terminating_signals. Fortunately,
239 this is possible in Posix. Unfortunately, we have to call signal ()
240 on non-Posix systems for each signal in terminating_signals. */
241 #if defined (HAVE_POSIX_SIGNALS)
242 act.sa_handler = termsig_sighandler;
244 sigemptyset (&act.sa_mask);
245 sigemptyset (&oact.sa_mask);
246 for (i = 0; i < TERMSIGS_LENGTH; i++)
247 sigaddset (&act.sa_mask, XSIG (i));
248 for (i = 0; i < TERMSIGS_LENGTH; i++)
250 /* If we've already trapped it, don't do anything. */
251 if (signal_is_trapped (XSIG (i)))
254 sigaction (XSIG (i), &act, &oact);
255 XHANDLER(i) = oact.sa_handler;
256 XSAFLAGS(i) = oact.sa_flags;
257 /* Don't do anything with signals that are ignored at shell entry
258 if the shell is not interactive. */
259 /* XXX - should we do this for interactive shells, too? */
260 if (interactive_shell == 0 && XHANDLER (i) == SIG_IGN)
262 sigaction (XSIG (i), &oact, &act);
263 set_signal_ignored (XSIG (i));
265 #if defined (SIGPROF) && !defined (_MINIX)
266 if (XSIG (i) == SIGPROF && XHANDLER (i) != SIG_DFL && XHANDLER (i) != SIG_IGN)
267 sigaction (XSIG (i), &oact, (struct sigaction *)NULL);
268 #endif /* SIGPROF && !_MINIX */
271 #else /* !HAVE_POSIX_SIGNALS */
273 for (i = 0; i < TERMSIGS_LENGTH; i++)
275 /* If we've already trapped it, don't do anything. */
276 if (signal_is_trapped (XSIG (i)))
279 XHANDLER(i) = signal (XSIG (i), termsig_sighandler);
281 /* Don't do anything with signals that are ignored at shell entry
282 if the shell is not interactive. */
283 /* XXX - should we do this for interactive shells, too? */
284 if (interactive_shell == 0 && XHANDLER (i) == SIG_IGN)
286 signal (XSIG (i), SIG_IGN);
287 set_signal_ignored (XSIG (i));
290 if (XSIG (i) == SIGPROF && XHANDLER (i) != SIG_DFL && XHANDLER (i) != SIG_IGN)
291 signal (XSIG (i), XHANDLER (i));
295 #endif /* !HAVE_POSIX_SIGNALS */
297 termsigs_initialized = 1;
301 initialize_shell_signals ()
304 initialize_terminating_signals ();
306 #if defined (JOB_CONTROL) || defined (HAVE_POSIX_SIGNALS)
307 /* All shells use the signal mask they inherit, and pass it along
308 to child processes. Children will never block SIGCHLD, though. */
309 sigemptyset (&top_level_mask);
310 sigprocmask (SIG_BLOCK, (sigset_t *)NULL, &top_level_mask);
311 # if defined (SIGCHLD)
312 sigdelset (&top_level_mask, SIGCHLD);
314 #endif /* JOB_CONTROL || HAVE_POSIX_SIGNALS */
316 /* And, some signals that are specifically ignored by the shell. */
317 set_signal_handler (SIGQUIT, SIG_IGN);
321 set_signal_handler (SIGINT, sigint_sighandler);
322 set_signal_handler (SIGTERM, SIG_IGN);
323 set_sigwinch_handler ();
328 reset_terminating_signals ()
331 #if defined (HAVE_POSIX_SIGNALS)
332 struct sigaction act;
335 if (termsigs_initialized == 0)
338 #if defined (HAVE_POSIX_SIGNALS)
340 sigemptyset (&act.sa_mask);
341 for (i = 0; i < TERMSIGS_LENGTH; i++)
343 /* Skip a signal if it's trapped or handled specially, because the
344 trap code will restore the correct value. */
345 if (signal_is_trapped (XSIG (i)) || signal_is_special (XSIG (i)))
348 act.sa_handler = XHANDLER (i);
349 act.sa_flags = XSAFLAGS (i);
350 sigaction (XSIG (i), &act, (struct sigaction *) NULL);
352 #else /* !HAVE_POSIX_SIGNALS */
353 for (i = 0; i < TERMSIGS_LENGTH; i++)
355 if (signal_is_trapped (XSIG (i)) || signal_is_special (XSIG (i)))
358 signal (XSIG (i), XHANDLER (i));
360 #endif /* !HAVE_POSIX_SIGNALS */
365 /* Run some of the cleanups that should be performed when we run
366 jump_to_top_level from a builtin command context. XXX - might want to
367 also call reset_parser here. */
371 /* Clean up string parser environment. */
372 while (parse_and_execute_level)
373 parse_and_execute_cleanup ();
375 #if defined (PROCESS_SUBSTITUTION)
377 #endif /* PROCESS_SUBSTITUTION */
379 run_unwind_protects ();
380 loop_level = continuing = breaking = funcnest = 0;
381 executing_list = comsub_ignore_return = return_catch_flag = 0;
384 /* What to do when we've been interrupted, and it is safe to handle it. */
386 throw_to_top_level ()
388 int print_newline = 0;
399 last_command_exit_signal = (last_command_exit_value > 128) ?
400 (last_command_exit_value - 128) : 0;
401 last_command_exit_value |= 128;
403 /* Run any traps set on SIGINT. */
404 run_interrupt_trap ();
406 /* Clean up string parser environment. */
407 while (parse_and_execute_level)
408 parse_and_execute_cleanup ();
410 #if defined (JOB_CONTROL)
411 give_terminal_to (shell_pgrp, 0);
412 #endif /* JOB_CONTROL */
414 #if defined (JOB_CONTROL) || defined (HAVE_POSIX_SIGNALS)
415 /* This should not be necessary on systems using sigsetjmp/siglongjmp. */
416 sigprocmask (SIG_SETMASK, &top_level_mask, (sigset_t *)NULL);
421 #if defined (READLINE)
424 #endif /* READLINE */
426 #if defined (PROCESS_SUBSTITUTION)
428 #endif /* PROCESS_SUBSTITUTION */
430 run_unwind_protects ();
431 loop_level = continuing = breaking = funcnest = 0;
432 executing_list = comsub_ignore_return = return_catch_flag = 0;
434 if (interactive && print_newline)
437 fprintf (stderr, "\n");
441 /* An interrupted `wait' command in a script does not exit the script. */
442 if (interactive || (interactive_shell && !shell_initialized) ||
443 (print_newline && signal_is_trapped (SIGINT)))
444 jump_to_top_level (DISCARD);
446 jump_to_top_level (EXITPROG);
449 /* This is just here to isolate the longjmp calls. */
451 jump_to_top_level (value)
454 longjmp (top_level, value);
458 termsig_sighandler (sig)
461 /* If we get called twice with the same signal before handling it,
462 terminate right away. */
500 sig == terminating_signal)
501 terminate_immediately = 1;
503 terminating_signal = sig;
505 /* XXX - should this also trigger when interrupt_immediately is set? */
506 if (terminate_immediately)
508 #if defined (HISTORY)
509 /* XXX - will inhibit history file being written */
510 # if defined (READLINE)
511 if (interactive_shell == 0 || interactive == 0 || (sig != SIGHUP && sig != SIGTERM) || no_line_editing || (RL_ISSTATE (RL_STATE_READCMD) == 0))
513 history_lines_this_session = 0;
515 terminate_immediately = 0;
516 termsig_handler (sig);
523 termsig_handler (sig)
526 static int handling_termsig = 0;
528 /* Simple semaphore to keep this function from being executed multiple
529 times. Since we no longer are running as a signal handler, we don't
530 block multiple occurrences of the terminating signals while running. */
531 if (handling_termsig)
533 handling_termsig = 1;
534 terminating_signal = 0; /* keep macro from re-testing true. */
536 /* I don't believe this condition ever tests true. */
537 if (sig == SIGINT && signal_is_trapped (SIGINT))
538 run_interrupt_trap ();
540 #if defined (HISTORY)
541 if (interactive_shell && sig != SIGABRT)
542 maybe_save_shell_history ();
545 #if defined (JOB_CONTROL)
546 if (sig == SIGHUP && (interactive || (subshell_environment & (SUBSHELL_COMSUB|SUBSHELL_PROCSUB))))
549 #endif /* JOB_CONTROL */
551 #if defined (PROCESS_SUBSTITUTION)
553 #endif /* PROCESS_SUBSTITUTION */
555 /* Reset execution context */
556 loop_level = continuing = breaking = funcnest = 0;
557 executing_list = comsub_ignore_return = return_catch_flag = 0;
560 set_signal_handler (sig, SIG_DFL);
561 kill (getpid (), sig);
564 /* What we really do when SIGINT occurs. */
566 sigint_sighandler (sig)
569 #if defined (MUST_REINSTALL_SIGHANDLERS)
570 signal (sig, sigint_sighandler);
573 /* interrupt_state needs to be set for the stack of interrupts to work
574 right. Should it be set unconditionally? */
575 if (interrupt_state == 0)
578 if (interrupt_immediately)
580 interrupt_immediately = 0;
581 last_command_exit_value = 128 + sig;
582 throw_to_top_level ();
588 #if defined (SIGWINCH)
590 sigwinch_sighandler (sig)
593 #if defined (MUST_REINSTALL_SIGHANDLERS)
594 set_signal_handler (SIGWINCH, sigwinch_sighandler);
595 #endif /* MUST_REINSTALL_SIGHANDLERS */
596 sigwinch_received = 1;
599 #endif /* SIGWINCH */
602 set_sigwinch_handler ()
604 #if defined (SIGWINCH)
605 old_winch = set_signal_handler (SIGWINCH, sigwinch_sighandler);
610 unset_sigwinch_handler ()
612 #if defined (SIGWINCH)
613 set_signal_handler (SIGWINCH, old_winch);
617 /* Signal functions used by the rest of the code. */
618 #if !defined (HAVE_POSIX_SIGNALS)
620 #if defined (JOB_CONTROL)
621 /* Perform OPERATION on NEWSET, perhaps leaving information in OLDSET. */
622 sigprocmask (operation, newset, oldset)
623 int operation, *newset, *oldset;
635 old = sigblock (new);
643 internal_error (_("sigprocmask: %d: invalid operation"), operation);
649 #endif /* JOB_CONTROL */
653 #if !defined (SA_INTERRUPT)
654 # define SA_INTERRUPT 0
657 #if !defined (SA_RESTART)
658 # define SA_RESTART 0
662 set_signal_handler (sig, handler)
666 struct sigaction act, oact;
668 act.sa_handler = handler;
672 /* We don't want a child death to interrupt interruptible system calls, even
673 if we take the time to reap children */
675 act.sa_flags |= SA_RESTART; /* XXX */
677 sigemptyset (&act.sa_mask);
678 sigemptyset (&oact.sa_mask);
679 sigaction (sig, &act, &oact);
680 return (oact.sa_handler);
682 #endif /* HAVE_POSIX_SIGNALS */