]> git.ipfire.org Git - thirdparty/bash.git/blame - sig.c
commit bash-20100325 snapshot
[thirdparty/bash.git] / sig.c
CommitLineData
ccc6cda3
JA
1/* sig.c - interface for shell signal handlers and signal initialization. */
2
012bac39 3/* Copyright (C) 1994-2009 Free Software Foundation, Inc.
ccc6cda3
JA
4
5 This file is part of GNU Bash, the Bourne Again SHell.
6
2e4498b3
CR
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.
ccc6cda3 11
2e4498b3
CR
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.
ccc6cda3 16
2e4498b3
CR
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/>.
19*/
ccc6cda3
JA
20
21#include "config.h"
22
23#include "bashtypes.h"
24
25#if defined (HAVE_UNISTD_H)
cce855bc
JA
26# ifdef _MINIX
27# include <sys/types.h>
28# endif
ccc6cda3
JA
29# include <unistd.h>
30#endif
31
32#include <stdio.h>
33#include <signal.h>
34
5e13499c
CR
35#include "bashintl.h"
36
ccc6cda3
JA
37#include "shell.h"
38#if defined (JOB_CONTROL)
39#include "jobs.h"
40#endif /* JOB_CONTROL */
41#include "siglist.h"
42#include "sig.h"
43#include "trap.h"
44
45#include "builtins/common.h"
46
47#if defined (READLINE)
48# include "bashline.h"
49#endif
50
51#if defined (HISTORY)
52# include "bashhist.h"
53#endif
54
55extern int last_command_exit_value;
d3a24ed2 56extern int last_command_exit_signal;
ccc6cda3
JA
57extern int return_catch_flag;
58extern int loop_level, continuing, breaking;
f1c4df24 59extern int executing_list;
012bac39 60extern int comsub_ignore_return;
ccc6cda3 61extern int parse_and_execute_level, shell_initialized;
ccc6cda3 62
68dfe178
CR
63extern void intialize_siglist ();
64
ccc6cda3 65/* Non-zero after SIGINT. */
ac18b312 66volatile int interrupt_state = 0;
ccc6cda3 67
7027abcb
CR
68/* Non-zero after SIGWINCH */
69volatile int sigwinch_received = 0;
70
ac18b312
CR
71/* Set to the value of any terminating signal received. */
72volatile int terminating_signal = 0;
73
ccc6cda3
JA
74/* The environment at the top-level R-E loop. We use this in
75 the case of error return. */
76procenv_t top_level;
77
78#if defined (JOB_CONTROL) || defined (HAVE_POSIX_SIGNALS)
79/* The signal masks that this shell runs with. */
80sigset_t top_level_mask;
81#endif /* JOB_CONTROL */
82
83/* When non-zero, we throw_to_top_level (). */
84int interrupt_immediately = 0;
85
ac18b312
CR
86/* When non-zero, we call the terminating signal handler immediately. */
87int terminate_immediately = 0;
88
7027abcb
CR
89#if defined (SIGWINCH)
90static SigHandler *old_winch = (SigHandler *)SIG_DFL;
91#endif
92
f73dda09 93static void initialize_shell_signals __P((void));
ccc6cda3
JA
94
95void
7117c2d2
JA
96initialize_signals (reinit)
97 int reinit;
ccc6cda3 98{
d166f048 99 initialize_shell_signals ();
ccc6cda3 100 initialize_job_signals ();
e8ce775d 101#if !defined (HAVE_SYS_SIGLIST) && !defined (HAVE_UNDER_SYS_SIGLIST) && !defined (HAVE_STRSIGNAL)
7117c2d2
JA
102 if (reinit == 0)
103 initialize_siglist ();
e8ce775d 104#endif /* !HAVE_SYS_SIGLIST && !HAVE_UNDER_SYS_SIGLIST && !HAVE_STRSIGNAL */
ccc6cda3
JA
105}
106
ccc6cda3
JA
107/* A structure describing a signal that terminates the shell if not
108 caught. The orig_handler member is present so children can reset
109 these signals back to their original handlers. */
110struct termsig {
111 int signum;
112 SigHandler *orig_handler;
898cc92e 113 int orig_flags;
ccc6cda3
JA
114};
115
116#define NULL_HANDLER (SigHandler *)SIG_DFL
117
118/* The list of signals that would terminate the shell if not caught.
119 We catch them, but just so that we can write the history file,
120 and so forth. */
121static struct termsig terminating_signals[] = {
122#ifdef SIGHUP
898cc92e 123{ SIGHUP, NULL_HANDLER, 0 },
ccc6cda3
JA
124#endif
125
126#ifdef SIGINT
898cc92e 127{ SIGINT, NULL_HANDLER, 0 },
ccc6cda3
JA
128#endif
129
130#ifdef SIGILL
898cc92e 131{ SIGILL, NULL_HANDLER, 0 },
ccc6cda3
JA
132#endif
133
134#ifdef SIGTRAP
898cc92e 135{ SIGTRAP, NULL_HANDLER, 0 },
ccc6cda3
JA
136#endif
137
138#ifdef SIGIOT
898cc92e 139{ SIGIOT, NULL_HANDLER, 0 },
ccc6cda3
JA
140#endif
141
142#ifdef SIGDANGER
898cc92e 143{ SIGDANGER, NULL_HANDLER, 0 },
ccc6cda3
JA
144#endif
145
146#ifdef SIGEMT
898cc92e 147{ SIGEMT, NULL_HANDLER, 0 },
ccc6cda3
JA
148#endif
149
150#ifdef SIGFPE
898cc92e 151{ SIGFPE, NULL_HANDLER, 0 },
ccc6cda3
JA
152#endif
153
154#ifdef SIGBUS
898cc92e 155{ SIGBUS, NULL_HANDLER, 0 },
ccc6cda3
JA
156#endif
157
158#ifdef SIGSEGV
898cc92e 159{ SIGSEGV, NULL_HANDLER, 0 },
ccc6cda3
JA
160#endif
161
162#ifdef SIGSYS
898cc92e 163{ SIGSYS, NULL_HANDLER, 0 },
ccc6cda3
JA
164#endif
165
166#ifdef SIGPIPE
898cc92e 167{ SIGPIPE, NULL_HANDLER, 0 },
ccc6cda3
JA
168#endif
169
170#ifdef SIGALRM
898cc92e 171{ SIGALRM, NULL_HANDLER, 0 },
ccc6cda3
JA
172#endif
173
174#ifdef SIGTERM
898cc92e 175{ SIGTERM, NULL_HANDLER, 0 },
ccc6cda3
JA
176#endif
177
178#ifdef SIGXCPU
898cc92e 179{ SIGXCPU, NULL_HANDLER, 0 },
ccc6cda3
JA
180#endif
181
182#ifdef SIGXFSZ
898cc92e 183{ SIGXFSZ, NULL_HANDLER, 0 },
ccc6cda3
JA
184#endif
185
186#ifdef SIGVTALRM
898cc92e 187{ SIGVTALRM, NULL_HANDLER, 0 },
ccc6cda3
JA
188#endif
189
bb70624e 190#if 0
ccc6cda3 191#ifdef SIGPROF
898cc92e 192{ SIGPROF, NULL_HANDLER, 0 },
ccc6cda3 193#endif
bb70624e 194#endif
ccc6cda3
JA
195
196#ifdef SIGLOST
898cc92e 197{ SIGLOST, NULL_HANDLER, 0 },
ccc6cda3
JA
198#endif
199
200#ifdef SIGUSR1
898cc92e 201{ SIGUSR1, NULL_HANDLER, 0 },
ccc6cda3
JA
202#endif
203
204#ifdef SIGUSR2
898cc92e 205{ SIGUSR2, NULL_HANDLER, 0 },
ccc6cda3
JA
206#endif
207};
208
209#define TERMSIGS_LENGTH (sizeof (terminating_signals) / sizeof (struct termsig))
210
211#define XSIG(x) (terminating_signals[x].signum)
212#define XHANDLER(x) (terminating_signals[x].orig_handler)
898cc92e 213#define XSAFLAGS(x) (terminating_signals[x].orig_flags)
ccc6cda3 214
d166f048
JA
215static int termsigs_initialized = 0;
216
ccc6cda3 217/* Initialize signals that will terminate the shell to do some
d166f048 218 unwind protection. For non-interactive shells, we only call
9e51a74d
CR
219 this when a trap is defined for EXIT (0) or when trap is run
220 to display signal dispositions. */
d166f048 221void
ccc6cda3
JA
222initialize_terminating_signals ()
223{
224 register int i;
d166f048
JA
225#if defined (HAVE_POSIX_SIGNALS)
226 struct sigaction act, oact;
227#endif
228
229 if (termsigs_initialized)
230 return;
ccc6cda3
JA
231
232 /* The following code is to avoid an expensive call to
233 set_signal_handler () for each terminating_signals. Fortunately,
234 this is possible in Posix. Unfortunately, we have to call signal ()
235 on non-Posix systems for each signal in terminating_signals. */
236#if defined (HAVE_POSIX_SIGNALS)
ac18b312 237 act.sa_handler = termsig_sighandler;
ccc6cda3
JA
238 act.sa_flags = 0;
239 sigemptyset (&act.sa_mask);
240 sigemptyset (&oact.sa_mask);
241 for (i = 0; i < TERMSIGS_LENGTH; i++)
242 sigaddset (&act.sa_mask, XSIG (i));
243 for (i = 0; i < TERMSIGS_LENGTH; i++)
244 {
7117c2d2
JA
245 /* If we've already trapped it, don't do anything. */
246 if (signal_is_trapped (XSIG (i)))
247 continue;
248
ccc6cda3 249 sigaction (XSIG (i), &act, &oact);
d166f048 250 XHANDLER(i) = oact.sa_handler;
898cc92e 251 XSAFLAGS(i) = oact.sa_flags;
ccc6cda3
JA
252 /* Don't do anything with signals that are ignored at shell entry
253 if the shell is not interactive. */
9e51a74d
CR
254 /* XXX - should we do this for interactive shells, too? */
255 if (interactive_shell == 0 && XHANDLER (i) == SIG_IGN)
28ef6c31 256 {
ccc6cda3
JA
257 sigaction (XSIG (i), &oact, &act);
258 set_signal_ignored (XSIG (i));
28ef6c31 259 }
cce855bc 260#if defined (SIGPROF) && !defined (_MINIX)
d166f048 261 if (XSIG (i) == SIGPROF && XHANDLER (i) != SIG_DFL && XHANDLER (i) != SIG_IGN)
28ef6c31 262 sigaction (XSIG (i), &oact, (struct sigaction *)NULL);
cce855bc 263#endif /* SIGPROF && !_MINIX */
ccc6cda3
JA
264 }
265
266#else /* !HAVE_POSIX_SIGNALS */
267
268 for (i = 0; i < TERMSIGS_LENGTH; i++)
269 {
7117c2d2
JA
270 /* If we've already trapped it, don't do anything. */
271 if (signal_is_trapped (XSIG (i)))
272 continue;
273
ac18b312 274 XHANDLER(i) = signal (XSIG (i), termsig_sighandler);
898cc92e 275 XSAFLAGS(i) = 0;
ccc6cda3
JA
276 /* Don't do anything with signals that are ignored at shell entry
277 if the shell is not interactive. */
9e51a74d
CR
278 /* XXX - should we do this for interactive shells, too? */
279 if (interactive_shell == 0 && XHANDLER (i) == SIG_IGN)
ccc6cda3 280 {
28ef6c31
JA
281 signal (XSIG (i), SIG_IGN);
282 set_signal_ignored (XSIG (i));
ccc6cda3 283 }
cce855bc 284#ifdef SIGPROF
d166f048 285 if (XSIG (i) == SIGPROF && XHANDLER (i) != SIG_DFL && XHANDLER (i) != SIG_IGN)
28ef6c31 286 signal (XSIG (i), XHANDLER (i));
cce855bc 287#endif
ccc6cda3
JA
288 }
289
290#endif /* !HAVE_POSIX_SIGNALS */
291
d166f048
JA
292 termsigs_initialized = 1;
293}
294
295static void
296initialize_shell_signals ()
297{
298 if (interactive)
299 initialize_terminating_signals ();
300
ccc6cda3
JA
301#if defined (JOB_CONTROL) || defined (HAVE_POSIX_SIGNALS)
302 /* All shells use the signal mask they inherit, and pass it along
303 to child processes. Children will never block SIGCHLD, though. */
304 sigemptyset (&top_level_mask);
305 sigprocmask (SIG_BLOCK, (sigset_t *)NULL, &top_level_mask);
bb70624e 306# if defined (SIGCHLD)
ccc6cda3 307 sigdelset (&top_level_mask, SIGCHLD);
bb70624e 308# endif
ccc6cda3
JA
309#endif /* JOB_CONTROL || HAVE_POSIX_SIGNALS */
310
311 /* And, some signals that are specifically ignored by the shell. */
312 set_signal_handler (SIGQUIT, SIG_IGN);
313
314 if (interactive)
315 {
316 set_signal_handler (SIGINT, sigint_sighandler);
317 set_signal_handler (SIGTERM, SIG_IGN);
7027abcb 318 set_sigwinch_handler ();
ccc6cda3
JA
319 }
320}
321
322void
323reset_terminating_signals ()
324{
325 register int i;
ccc6cda3
JA
326#if defined (HAVE_POSIX_SIGNALS)
327 struct sigaction act;
d166f048 328#endif
ccc6cda3 329
d166f048
JA
330 if (termsigs_initialized == 0)
331 return;
332
333#if defined (HAVE_POSIX_SIGNALS)
ccc6cda3
JA
334 act.sa_flags = 0;
335 sigemptyset (&act.sa_mask);
336 for (i = 0; i < TERMSIGS_LENGTH; i++)
337 {
338 /* Skip a signal if it's trapped or handled specially, because the
339 trap code will restore the correct value. */
340 if (signal_is_trapped (XSIG (i)) || signal_is_special (XSIG (i)))
341 continue;
342
343 act.sa_handler = XHANDLER (i);
898cc92e 344 act.sa_flags = XSAFLAGS (i);
ccc6cda3
JA
345 sigaction (XSIG (i), &act, (struct sigaction *) NULL);
346 }
347#else /* !HAVE_POSIX_SIGNALS */
348 for (i = 0; i < TERMSIGS_LENGTH; i++)
349 {
350 if (signal_is_trapped (XSIG (i)) || signal_is_special (XSIG (i)))
351 continue;
352
353 signal (XSIG (i), XHANDLER (i));
354 }
355#endif /* !HAVE_POSIX_SIGNALS */
356}
357#undef XSIG
358#undef XHANDLER
359
d3ad40de
CR
360/* Run some of the cleanups that should be performed when we run
361 jump_to_top_level from a builtin command context. XXX - might want to
362 also call reset_parser here. */
363void
364top_level_cleanup ()
365{
366 /* Clean up string parser environment. */
367 while (parse_and_execute_level)
368 parse_and_execute_cleanup ();
369
370#if defined (PROCESS_SUBSTITUTION)
371 unlink_fifo_list ();
372#endif /* PROCESS_SUBSTITUTION */
373
374 run_unwind_protects ();
012bac39
CR
375 loop_level = continuing = breaking = 0;
376 executing_list = comsub_ignore_return = return_catch_flag = 0;
d3ad40de
CR
377}
378
ccc6cda3
JA
379/* What to do when we've been interrupted, and it is safe to handle it. */
380void
381throw_to_top_level ()
382{
383 int print_newline = 0;
384
385 if (interrupt_state)
386 {
387 print_newline = 1;
388 DELINTERRUPT;
389 }
390
391 if (interrupt_state)
392 return;
393
d3a24ed2
CR
394 last_command_exit_signal = (last_command_exit_value > 128) ?
395 (last_command_exit_value - 128) : 0;
ccc6cda3
JA
396 last_command_exit_value |= 128;
397
398 /* Run any traps set on SIGINT. */
399 run_interrupt_trap ();
400
d3ad40de 401 /* Clean up string parser environment. */
ccc6cda3
JA
402 while (parse_and_execute_level)
403 parse_and_execute_cleanup ();
404
405#if defined (JOB_CONTROL)
28ef6c31 406 give_terminal_to (shell_pgrp, 0);
ccc6cda3
JA
407#endif /* JOB_CONTROL */
408
409#if defined (JOB_CONTROL) || defined (HAVE_POSIX_SIGNALS)
410 /* This should not be necessary on systems using sigsetjmp/siglongjmp. */
411 sigprocmask (SIG_SETMASK, &top_level_mask, (sigset_t *)NULL);
412#endif
413
414 reset_parser ();
415
416#if defined (READLINE)
417 if (interactive)
8943768b 418 bashline_reset ();
ccc6cda3
JA
419#endif /* READLINE */
420
421#if defined (PROCESS_SUBSTITUTION)
422 unlink_fifo_list ();
423#endif /* PROCESS_SUBSTITUTION */
424
425 run_unwind_protects ();
012bac39
CR
426 loop_level = continuing = breaking = 0;
427 executing_list = comsub_ignore_return = return_catch_flag = 0;
ccc6cda3
JA
428
429 if (interactive && print_newline)
430 {
431 fflush (stdout);
432 fprintf (stderr, "\n");
433 fflush (stderr);
434 }
435
436 /* An interrupted `wait' command in a script does not exit the script. */
437 if (interactive || (interactive_shell && !shell_initialized) ||
438 (print_newline && signal_is_trapped (SIGINT)))
439 jump_to_top_level (DISCARD);
440 else
441 jump_to_top_level (EXITPROG);
442}
443
444/* This is just here to isolate the longjmp calls. */
445void
446jump_to_top_level (value)
447 int value;
448{
449 longjmp (top_level, value);
450}
451
452sighandler
ac18b312 453termsig_sighandler (sig)
ccc6cda3
JA
454 int sig;
455{
c302751c
CR
456 /* If we get called twice with the same signal before handling it,
457 terminate right away. */
458 if (
459#ifdef SIGHUP
460 sig != SIGHUP &&
461#endif
462#ifdef SIGINT
463 sig != SIGINT &&
464#endif
465#ifdef SIGDANGER
466 sig != SIGDANGER &&
467#endif
468#ifdef SIGPIPE
469 sig != SIGPIPE &&
470#endif
471#ifdef SIGALRM
472 sig != SIGALRM &&
473#endif
474#ifdef SIGTERM
475 sig != SIGTERM &&
476#endif
477#ifdef SIGXCPU
478 sig != SIGXCPU &&
479#endif
480#ifdef SIGXFSZ
481 sig != SIGXFSZ &&
482#endif
483#ifdef SIGVTALRM
484 sig != SIGVTALRM &&
485#endif
486#ifdef SIGLOST
487 sig != SIGLOST &&
488#endif
489#ifdef SIGUSR1
490 sig != SIGUSR1 &&
491#endif
492#ifdef SIGUSR2
493 sig != SIGUSR2 &&
494#endif
495 sig == terminating_signal)
496 terminate_immediately = 1;
497
ac18b312
CR
498 terminating_signal = sig;
499
c92a890b 500 /* XXX - should this also trigger when interrupt_immediately is set? */
ac18b312
CR
501 if (terminate_immediately)
502 {
503 terminate_immediately = 0;
504 termsig_handler (sig);
505 }
506
507 SIGRETURN (0);
508}
509
510void
511termsig_handler (sig)
512 int sig;
513{
514 static int handling_termsig = 0;
515
516 /* Simple semaphore to keep this function from being executed multiple
517 times. Since we no longer are running as a signal handler, we don't
518 block multiple occurrences of the terminating signals while running. */
519 if (handling_termsig)
520 return;
521 handling_termsig = 1;
522 terminating_signal = 0; /* keep macro from re-testing true. */
523
668f5007 524 /* I don't believe this condition ever tests true. */
ccc6cda3
JA
525 if (sig == SIGINT && signal_is_trapped (SIGINT))
526 run_interrupt_trap ();
527
528#if defined (HISTORY)
529 if (interactive_shell && sig != SIGABRT)
530 maybe_save_shell_history ();
531#endif /* HISTORY */
532
533#if defined (JOB_CONTROL)
691aebcb 534 if (sig == SIGHUP && (interactive || (subshell_environment & (SUBSHELL_COMSUB|SUBSHELL_PROCSUB))))
ccc6cda3
JA
535 hangup_all_jobs ();
536 end_job_control ();
537#endif /* JOB_CONTROL */
538
539#if defined (PROCESS_SUBSTITUTION)
540 unlink_fifo_list ();
541#endif /* PROCESS_SUBSTITUTION */
542
c92a890b 543 /* Reset execution context */
012bac39
CR
544 loop_level = continuing = breaking = 0;
545 executing_list = comsub_ignore_return = return_catch_flag = 0;
c92a890b 546
ccc6cda3
JA
547 run_exit_trap ();
548 set_signal_handler (sig, SIG_DFL);
549 kill (getpid (), sig);
ccc6cda3
JA
550}
551
552/* What we really do when SIGINT occurs. */
553sighandler
554sigint_sighandler (sig)
555 int sig;
556{
557#if defined (MUST_REINSTALL_SIGHANDLERS)
558 signal (sig, sigint_sighandler);
559#endif
560
561 /* interrupt_state needs to be set for the stack of interrupts to work
562 right. Should it be set unconditionally? */
563 if (interrupt_state == 0)
564 ADDINTERRUPT;
866961ad 565
ccc6cda3
JA
566 if (interrupt_immediately)
567 {
568 interrupt_immediately = 0;
6932f7f5 569 last_command_exit_value = 128 + sig;
ccc6cda3
JA
570 throw_to_top_level ();
571 }
572
573 SIGRETURN (0);
574}
575
7027abcb
CR
576#if defined (SIGWINCH)
577sighandler
578sigwinch_sighandler (sig)
579 int sig;
580{
581#if defined (MUST_REINSTALL_SIGHANDLERS)
582 set_signal_handler (SIGWINCH, sigwinch_sighandler);
583#endif /* MUST_REINSTALL_SIGHANDLERS */
584 sigwinch_received = 1;
585 SIGRETURN (0);
586}
587#endif /* SIGWINCH */
588
589void
590set_sigwinch_handler ()
591{
592#if defined (SIGWINCH)
593 old_winch = set_signal_handler (SIGWINCH, sigwinch_sighandler);
594#endif
595}
596
597void
598unset_sigwinch_handler ()
599{
600#if defined (SIGWINCH)
601 set_signal_handler (SIGWINCH, old_winch);
602#endif
603}
604
ccc6cda3
JA
605/* Signal functions used by the rest of the code. */
606#if !defined (HAVE_POSIX_SIGNALS)
607
608#if defined (JOB_CONTROL)
609/* Perform OPERATION on NEWSET, perhaps leaving information in OLDSET. */
610sigprocmask (operation, newset, oldset)
611 int operation, *newset, *oldset;
612{
613 int old, new;
614
615 if (newset)
616 new = *newset;
617 else
618 new = 0;
619
620 switch (operation)
621 {
622 case SIG_BLOCK:
623 old = sigblock (new);
624 break;
625
626 case SIG_SETMASK:
627 sigsetmask (new);
628 break;
629
630 default:
5e13499c 631 internal_error (_("sigprocmask: %d: invalid operation"), operation);
ccc6cda3
JA
632 }
633
634 if (oldset)
635 *oldset = old;
636}
637#endif /* JOB_CONTROL */
638
639#else
640
641#if !defined (SA_INTERRUPT)
642# define SA_INTERRUPT 0
643#endif
644
645#if !defined (SA_RESTART)
646# define SA_RESTART 0
647#endif
648
649SigHandler *
650set_signal_handler (sig, handler)
651 int sig;
652 SigHandler *handler;
653{
654 struct sigaction act, oact;
655
656 act.sa_handler = handler;
657 act.sa_flags = 0;
9e51a74d
CR
658
659 /* XXX - bash-4.2 */
660 /* We don't want a child death to interrupt interruptible system calls, even
661 if we take the time to reap children */
662 if (sig == SIGCHLD)
ccc6cda3 663 act.sa_flags |= SA_RESTART; /* XXX */
9e51a74d 664
ccc6cda3
JA
665 sigemptyset (&act.sa_mask);
666 sigemptyset (&oact.sa_mask);
667 sigaction (sig, &act, &oact);
668 return (oact.sa_handler);
669}
670#endif /* HAVE_POSIX_SIGNALS */