1 /* sig.c - interface for shell signal handlers and signal initialization. */
3 /* Copyright (C) 1994-2006 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 it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
12 Bash is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 You should have received a copy of the GNU General Public License along
18 with Bash; see the file COPYING. If not, write to the Free Software
19 Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
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 parse_and_execute_level
, shell_initialized
;
61 /* Non-zero after SIGINT. */
62 volatile int interrupt_state
= 0;
64 /* Non-zero after SIGWINCH */
65 volatile int sigwinch_received
= 0;
67 /* Set to the value of any terminating signal received. */
68 volatile int terminating_signal
= 0;
70 /* The environment at the top-level R-E loop. We use this in
71 the case of error return. */
74 #if defined (JOB_CONTROL) || defined (HAVE_POSIX_SIGNALS)
75 /* The signal masks that this shell runs with. */
76 sigset_t top_level_mask
;
77 #endif /* JOB_CONTROL */
79 /* When non-zero, we throw_to_top_level (). */
80 int interrupt_immediately
= 0;
82 /* When non-zero, we call the terminating signal handler immediately. */
83 int terminate_immediately
= 0;
85 #if defined (SIGWINCH)
86 static SigHandler
*old_winch
= (SigHandler
*)SIG_DFL
;
89 static void initialize_shell_signals
__P((void));
92 initialize_signals (reinit
)
95 initialize_shell_signals ();
96 initialize_job_signals ();
97 #if !defined (HAVE_SYS_SIGLIST) && !defined (HAVE_UNDER_SYS_SIGLIST) && !defined (HAVE_STRSIGNAL)
99 initialize_siglist ();
100 #endif /* !HAVE_SYS_SIGLIST && !HAVE_UNDER_SYS_SIGLIST && !HAVE_STRSIGNAL */
103 /* A structure describing a signal that terminates the shell if not
104 caught. The orig_handler member is present so children can reset
105 these signals back to their original handlers. */
108 SigHandler
*orig_handler
;
112 #define NULL_HANDLER (SigHandler *)SIG_DFL
114 /* The list of signals that would terminate the shell if not caught.
115 We catch them, but just so that we can write the history file,
117 static struct termsig terminating_signals
[] = {
119 { SIGHUP
, NULL_HANDLER
, 0 },
123 { SIGINT
, NULL_HANDLER
, 0 },
127 { SIGILL
, NULL_HANDLER
, 0 },
131 { SIGTRAP
, NULL_HANDLER
, 0 },
135 { SIGIOT
, NULL_HANDLER
, 0 },
139 { SIGDANGER
, NULL_HANDLER
, 0 },
143 { SIGEMT
, NULL_HANDLER
, 0 },
147 { SIGFPE
, NULL_HANDLER
, 0 },
151 { SIGBUS
, NULL_HANDLER
, 0 },
155 { SIGSEGV
, NULL_HANDLER
, 0 },
159 { SIGSYS
, NULL_HANDLER
, 0 },
163 { SIGPIPE
, NULL_HANDLER
, 0 },
167 { SIGALRM
, NULL_HANDLER
, 0 },
171 { SIGTERM
, NULL_HANDLER
, 0 },
175 { SIGXCPU
, NULL_HANDLER
, 0 },
179 { SIGXFSZ
, NULL_HANDLER
, 0 },
183 { SIGVTALRM
, NULL_HANDLER
, 0 },
188 { SIGPROF
, NULL_HANDLER
, 0 },
193 { SIGLOST
, NULL_HANDLER
, 0 },
197 { SIGUSR1
, NULL_HANDLER
, 0 },
201 { SIGUSR2
, NULL_HANDLER
, 0 },
205 #define TERMSIGS_LENGTH (sizeof (terminating_signals) / sizeof (struct termsig))
207 #define XSIG(x) (terminating_signals[x].signum)
208 #define XHANDLER(x) (terminating_signals[x].orig_handler)
209 #define XSAFLAGS(x) (terminating_signals[x].orig_flags)
211 static int termsigs_initialized
= 0;
213 /* Initialize signals that will terminate the shell to do some
214 unwind protection. For non-interactive shells, we only call
215 this when a trap is defined for EXIT (0). */
217 initialize_terminating_signals ()
220 #if defined (HAVE_POSIX_SIGNALS)
221 struct sigaction act
, oact
;
224 if (termsigs_initialized
)
227 /* The following code is to avoid an expensive call to
228 set_signal_handler () for each terminating_signals. Fortunately,
229 this is possible in Posix. Unfortunately, we have to call signal ()
230 on non-Posix systems for each signal in terminating_signals. */
231 #if defined (HAVE_POSIX_SIGNALS)
232 act
.sa_handler
= termsig_sighandler
;
234 sigemptyset (&act
.sa_mask
);
235 sigemptyset (&oact
.sa_mask
);
236 for (i
= 0; i
< TERMSIGS_LENGTH
; i
++)
237 sigaddset (&act
.sa_mask
, XSIG (i
));
238 for (i
= 0; i
< TERMSIGS_LENGTH
; i
++)
240 /* If we've already trapped it, don't do anything. */
241 if (signal_is_trapped (XSIG (i
)))
244 sigaction (XSIG (i
), &act
, &oact
);
245 XHANDLER(i
) = oact
.sa_handler
;
246 XSAFLAGS(i
) = oact
.sa_flags
;
247 /* Don't do anything with signals that are ignored at shell entry
248 if the shell is not interactive. */
249 if (!interactive_shell
&& XHANDLER (i
) == SIG_IGN
)
251 sigaction (XSIG (i
), &oact
, &act
);
252 set_signal_ignored (XSIG (i
));
254 #if defined (SIGPROF) && !defined (_MINIX)
255 if (XSIG (i
) == SIGPROF
&& XHANDLER (i
) != SIG_DFL
&& XHANDLER (i
) != SIG_IGN
)
256 sigaction (XSIG (i
), &oact
, (struct sigaction
*)NULL
);
257 #endif /* SIGPROF && !_MINIX */
260 #else /* !HAVE_POSIX_SIGNALS */
262 for (i
= 0; i
< TERMSIGS_LENGTH
; i
++)
264 /* If we've already trapped it, don't do anything. */
265 if (signal_is_trapped (XSIG (i
)))
268 XHANDLER(i
) = signal (XSIG (i
), termsig_sighandler
);
270 /* Don't do anything with signals that are ignored at shell entry
271 if the shell is not interactive. */
272 if (!interactive_shell
&& XHANDLER (i
) == SIG_IGN
)
274 signal (XSIG (i
), SIG_IGN
);
275 set_signal_ignored (XSIG (i
));
278 if (XSIG (i
) == SIGPROF
&& XHANDLER (i
) != SIG_DFL
&& XHANDLER (i
) != SIG_IGN
)
279 signal (XSIG (i
), XHANDLER (i
));
283 #endif /* !HAVE_POSIX_SIGNALS */
285 termsigs_initialized
= 1;
289 initialize_shell_signals ()
292 initialize_terminating_signals ();
294 #if defined (JOB_CONTROL) || defined (HAVE_POSIX_SIGNALS)
295 /* All shells use the signal mask they inherit, and pass it along
296 to child processes. Children will never block SIGCHLD, though. */
297 sigemptyset (&top_level_mask
);
298 sigprocmask (SIG_BLOCK
, (sigset_t
*)NULL
, &top_level_mask
);
299 # if defined (SIGCHLD)
300 sigdelset (&top_level_mask
, SIGCHLD
);
302 #endif /* JOB_CONTROL || HAVE_POSIX_SIGNALS */
304 /* And, some signals that are specifically ignored by the shell. */
305 set_signal_handler (SIGQUIT
, SIG_IGN
);
309 set_signal_handler (SIGINT
, sigint_sighandler
);
310 set_signal_handler (SIGTERM
, SIG_IGN
);
311 set_sigwinch_handler ();
316 reset_terminating_signals ()
319 #if defined (HAVE_POSIX_SIGNALS)
320 struct sigaction act
;
323 if (termsigs_initialized
== 0)
326 #if defined (HAVE_POSIX_SIGNALS)
328 sigemptyset (&act
.sa_mask
);
329 for (i
= 0; i
< TERMSIGS_LENGTH
; i
++)
331 /* Skip a signal if it's trapped or handled specially, because the
332 trap code will restore the correct value. */
333 if (signal_is_trapped (XSIG (i
)) || signal_is_special (XSIG (i
)))
336 act
.sa_handler
= XHANDLER (i
);
337 act
.sa_flags
= XSAFLAGS (i
);
338 sigaction (XSIG (i
), &act
, (struct sigaction
*) NULL
);
340 #else /* !HAVE_POSIX_SIGNALS */
341 for (i
= 0; i
< TERMSIGS_LENGTH
; i
++)
343 if (signal_is_trapped (XSIG (i
)) || signal_is_special (XSIG (i
)))
346 signal (XSIG (i
), XHANDLER (i
));
348 #endif /* !HAVE_POSIX_SIGNALS */
353 /* What to do when we've been interrupted, and it is safe to handle it. */
355 throw_to_top_level ()
357 int print_newline
= 0;
368 last_command_exit_signal
= (last_command_exit_value
> 128) ?
369 (last_command_exit_value
- 128) : 0;
370 last_command_exit_value
|= 128;
372 /* Run any traps set on SIGINT. */
373 run_interrupt_trap ();
375 /* Cleanup string parser environment. */
376 while (parse_and_execute_level
)
377 parse_and_execute_cleanup ();
379 #if defined (JOB_CONTROL)
380 give_terminal_to (shell_pgrp
, 0);
381 #endif /* JOB_CONTROL */
383 #if defined (JOB_CONTROL) || defined (HAVE_POSIX_SIGNALS)
384 /* This should not be necessary on systems using sigsetjmp/siglongjmp. */
385 sigprocmask (SIG_SETMASK
, &top_level_mask
, (sigset_t
*)NULL
);
390 #if defined (READLINE)
392 bashline_reinitialize ();
393 #endif /* READLINE */
395 #if defined (PROCESS_SUBSTITUTION)
397 #endif /* PROCESS_SUBSTITUTION */
399 run_unwind_protects ();
400 loop_level
= continuing
= breaking
= 0;
401 return_catch_flag
= 0;
403 if (interactive
&& print_newline
)
406 fprintf (stderr
, "\n");
410 /* An interrupted `wait' command in a script does not exit the script. */
411 if (interactive
|| (interactive_shell
&& !shell_initialized
) ||
412 (print_newline
&& signal_is_trapped (SIGINT
)))
413 jump_to_top_level (DISCARD
);
415 jump_to_top_level (EXITPROG
);
418 /* This is just here to isolate the longjmp calls. */
420 jump_to_top_level (value
)
423 longjmp (top_level
, value
);
427 termsig_sighandler (sig
)
430 terminating_signal
= sig
;
432 if (terminate_immediately
)
434 terminate_immediately
= 0;
435 termsig_handler (sig
);
442 termsig_handler (sig
)
445 static int handling_termsig
= 0;
447 /* Simple semaphore to keep this function from being executed multiple
448 times. Since we no longer are running as a signal handler, we don't
449 block multiple occurrences of the terminating signals while running. */
450 if (handling_termsig
)
452 handling_termsig
= 1;
453 terminating_signal
= 0; /* keep macro from re-testing true. */
455 /* I don't believe this condition ever tests true. */
456 if (sig
== SIGINT
&& signal_is_trapped (SIGINT
))
457 run_interrupt_trap ();
459 #if defined (HISTORY)
460 if (interactive_shell
&& sig
!= SIGABRT
)
461 maybe_save_shell_history ();
464 #if defined (JOB_CONTROL)
465 if (interactive
&& sig
== SIGHUP
)
468 #endif /* JOB_CONTROL */
470 #if defined (PROCESS_SUBSTITUTION)
472 #endif /* PROCESS_SUBSTITUTION */
475 set_signal_handler (sig
, SIG_DFL
);
476 kill (getpid (), sig
);
479 /* What we really do when SIGINT occurs. */
481 sigint_sighandler (sig
)
484 #if defined (MUST_REINSTALL_SIGHANDLERS)
485 signal (sig
, sigint_sighandler
);
488 /* interrupt_state needs to be set for the stack of interrupts to work
489 right. Should it be set unconditionally? */
490 if (interrupt_state
== 0)
493 if (interrupt_immediately
)
495 interrupt_immediately
= 0;
496 throw_to_top_level ();
502 #if defined (SIGWINCH)
504 sigwinch_sighandler (sig
)
507 #if defined (MUST_REINSTALL_SIGHANDLERS)
508 set_signal_handler (SIGWINCH
, sigwinch_sighandler
);
509 #endif /* MUST_REINSTALL_SIGHANDLERS */
510 sigwinch_received
= 1;
513 #endif /* SIGWINCH */
516 set_sigwinch_handler ()
518 #if defined (SIGWINCH)
519 old_winch
= set_signal_handler (SIGWINCH
, sigwinch_sighandler
);
524 unset_sigwinch_handler ()
526 #if defined (SIGWINCH)
527 set_signal_handler (SIGWINCH
, old_winch
);
531 /* Signal functions used by the rest of the code. */
532 #if !defined (HAVE_POSIX_SIGNALS)
534 #if defined (JOB_CONTROL)
535 /* Perform OPERATION on NEWSET, perhaps leaving information in OLDSET. */
536 sigprocmask (operation
, newset
, oldset
)
537 int operation
, *newset
, *oldset
;
549 old
= sigblock (new);
557 internal_error (_("sigprocmask: %d: invalid operation"), operation
);
563 #endif /* JOB_CONTROL */
567 #if !defined (SA_INTERRUPT)
568 # define SA_INTERRUPT 0
571 #if !defined (SA_RESTART)
572 # define SA_RESTART 0
576 set_signal_handler (sig
, handler
)
580 struct sigaction act
, oact
;
582 act
.sa_handler
= handler
;
586 act
.sa_flags
|= SA_INTERRUPT
; /* XXX */
588 act
.sa_flags
|= SA_RESTART
; /* XXX */
590 sigemptyset (&act
.sa_mask
);
591 sigemptyset (&oact
.sa_mask
);
592 sigaction (sig
, &act
, &oact
);
593 return (oact
.sa_handler
);
595 #endif /* HAVE_POSIX_SIGNALS */