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