Imported from ../bash-3.1.tar.gz.
[platform/upstream/bash.git] / sig.c
1 /* sig.c - interface for shell signal handlers and signal initialization. */
2
3 /* Copyright (C) 1994-2005 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 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
10    version.
11
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
15    for more details.
16
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. */
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
47 #if defined (READLINE)
48 #  include "bashline.h"
49 #endif
50
51 #if defined (HISTORY)
52 #  include "bashhist.h"
53 #endif
54
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;
60
61 /* Non-zero after SIGINT. */
62 int interrupt_state;
63
64 /* Non-zero after SIGWINCH */
65 volatile int sigwinch_received = 0;
66
67 /* The environment at the top-level R-E loop.  We use this in
68    the case of error return. */
69 procenv_t top_level;
70
71 #if defined (JOB_CONTROL) || defined (HAVE_POSIX_SIGNALS)
72 /* The signal masks that this shell runs with. */
73 sigset_t top_level_mask;
74 #endif /* JOB_CONTROL */
75
76 /* When non-zero, we throw_to_top_level (). */
77 int interrupt_immediately = 0;
78
79 #if defined (SIGWINCH)
80 static SigHandler *old_winch = (SigHandler *)SIG_DFL;
81 #endif
82
83 static void initialize_shell_signals __P((void));
84
85 void
86 initialize_signals (reinit)
87      int reinit;
88 {
89   initialize_shell_signals ();
90   initialize_job_signals ();
91 #if !defined (HAVE_SYS_SIGLIST) && !defined (HAVE_UNDER_SYS_SIGLIST) && !defined (HAVE_STRSIGNAL)
92   if (reinit == 0)
93     initialize_siglist ();
94 #endif /* !HAVE_SYS_SIGLIST && !HAVE_UNDER_SYS_SIGLIST && !HAVE_STRSIGNAL */
95 }
96
97 /* A structure describing a signal that terminates the shell if not
98    caught.  The orig_handler member is present so children can reset
99    these signals back to their original handlers. */
100 struct termsig {
101      int signum;
102      SigHandler *orig_handler;
103      int orig_flags;
104 };
105
106 #define NULL_HANDLER (SigHandler *)SIG_DFL
107
108 /* The list of signals that would terminate the shell if not caught.
109    We catch them, but just so that we can write the history file,
110    and so forth. */
111 static struct termsig terminating_signals[] = {
112 #ifdef SIGHUP
113 {  SIGHUP, NULL_HANDLER, 0 },
114 #endif
115
116 #ifdef SIGINT
117 {  SIGINT, NULL_HANDLER, 0 },
118 #endif
119
120 #ifdef SIGILL
121 {  SIGILL, NULL_HANDLER, 0 },
122 #endif
123
124 #ifdef SIGTRAP
125 {  SIGTRAP, NULL_HANDLER, 0 },
126 #endif
127
128 #ifdef SIGIOT
129 {  SIGIOT, NULL_HANDLER, 0 },
130 #endif
131
132 #ifdef SIGDANGER
133 {  SIGDANGER, NULL_HANDLER, 0 },
134 #endif
135
136 #ifdef SIGEMT
137 {  SIGEMT, NULL_HANDLER, 0 },
138 #endif
139
140 #ifdef SIGFPE
141 {  SIGFPE, NULL_HANDLER, 0 },
142 #endif
143
144 #ifdef SIGBUS
145 {  SIGBUS, NULL_HANDLER, 0 },
146 #endif
147
148 #ifdef SIGSEGV
149 {  SIGSEGV, NULL_HANDLER, 0 },
150 #endif
151
152 #ifdef SIGSYS
153 {  SIGSYS, NULL_HANDLER, 0 },
154 #endif
155
156 #ifdef SIGPIPE
157 {  SIGPIPE, NULL_HANDLER, 0 },
158 #endif
159
160 #ifdef SIGALRM
161 {  SIGALRM, NULL_HANDLER, 0 },
162 #endif
163
164 #ifdef SIGTERM
165 {  SIGTERM, NULL_HANDLER, 0 },
166 #endif
167
168 #ifdef SIGXCPU
169 {  SIGXCPU, NULL_HANDLER, 0 },
170 #endif
171
172 #ifdef SIGXFSZ
173 {  SIGXFSZ, NULL_HANDLER, 0 },
174 #endif
175
176 #ifdef SIGVTALRM
177 {  SIGVTALRM, NULL_HANDLER, 0 },
178 #endif
179
180 #if 0
181 #ifdef SIGPROF
182 {  SIGPROF, NULL_HANDLER, 0 },
183 #endif
184 #endif
185
186 #ifdef SIGLOST
187 {  SIGLOST, NULL_HANDLER, 0 },
188 #endif
189
190 #ifdef SIGUSR1
191 {  SIGUSR1, NULL_HANDLER, 0 },
192 #endif
193
194 #ifdef SIGUSR2
195 {  SIGUSR2, NULL_HANDLER, 0 },
196 #endif
197 };
198
199 #define TERMSIGS_LENGTH (sizeof (terminating_signals) / sizeof (struct termsig))
200
201 #define XSIG(x) (terminating_signals[x].signum)
202 #define XHANDLER(x) (terminating_signals[x].orig_handler)
203 #define XSAFLAGS(x) (terminating_signals[x].orig_flags)
204
205 static int termsigs_initialized = 0;
206
207 /* Initialize signals that will terminate the shell to do some
208    unwind protection.  For non-interactive shells, we only call
209    this when a trap is defined for EXIT (0). */
210 void
211 initialize_terminating_signals ()
212 {
213   register int i;
214 #if defined (HAVE_POSIX_SIGNALS)
215   struct sigaction act, oact;
216 #endif
217
218   if (termsigs_initialized)
219     return;
220
221   /* The following code is to avoid an expensive call to
222      set_signal_handler () for each terminating_signals.  Fortunately,
223      this is possible in Posix.  Unfortunately, we have to call signal ()
224      on non-Posix systems for each signal in terminating_signals. */
225 #if defined (HAVE_POSIX_SIGNALS)
226   act.sa_handler = termination_unwind_protect;
227   act.sa_flags = 0;
228   sigemptyset (&act.sa_mask);
229   sigemptyset (&oact.sa_mask);
230   for (i = 0; i < TERMSIGS_LENGTH; i++)
231     sigaddset (&act.sa_mask, XSIG (i));
232   for (i = 0; i < TERMSIGS_LENGTH; i++)
233     {
234       /* If we've already trapped it, don't do anything. */
235       if (signal_is_trapped (XSIG (i)))
236         continue;
237
238       sigaction (XSIG (i), &act, &oact);
239       XHANDLER(i) = oact.sa_handler;
240       XSAFLAGS(i) = oact.sa_flags;
241       /* Don't do anything with signals that are ignored at shell entry
242          if the shell is not interactive. */
243       if (!interactive_shell && XHANDLER (i) == SIG_IGN)
244         {
245           sigaction (XSIG (i), &oact, &act);
246           set_signal_ignored (XSIG (i));
247         }
248 #if defined (SIGPROF) && !defined (_MINIX)
249       if (XSIG (i) == SIGPROF && XHANDLER (i) != SIG_DFL && XHANDLER (i) != SIG_IGN)
250         sigaction (XSIG (i), &oact, (struct sigaction *)NULL);
251 #endif /* SIGPROF && !_MINIX */
252     }
253
254 #else /* !HAVE_POSIX_SIGNALS */
255
256   for (i = 0; i < TERMSIGS_LENGTH; i++)
257     {
258       /* If we've already trapped it, don't do anything. */
259       if (signal_is_trapped (XSIG (i)))
260         continue;
261
262       XHANDLER(i) = signal (XSIG (i), termination_unwind_protect);
263       XSAFLAGS(i) = 0;
264       /* Don't do anything with signals that are ignored at shell entry
265          if the shell is not interactive. */
266       if (!interactive_shell && XHANDLER (i) == SIG_IGN)
267         {
268           signal (XSIG (i), SIG_IGN);
269           set_signal_ignored (XSIG (i));
270         }
271 #ifdef SIGPROF
272       if (XSIG (i) == SIGPROF && XHANDLER (i) != SIG_DFL && XHANDLER (i) != SIG_IGN)
273         signal (XSIG (i), XHANDLER (i));
274 #endif
275     }
276
277 #endif /* !HAVE_POSIX_SIGNALS */
278
279   termsigs_initialized = 1;
280 }
281
282 static void
283 initialize_shell_signals ()
284 {
285   if (interactive)
286     initialize_terminating_signals ();
287
288 #if defined (JOB_CONTROL) || defined (HAVE_POSIX_SIGNALS)
289   /* All shells use the signal mask they inherit, and pass it along
290      to child processes.  Children will never block SIGCHLD, though. */
291   sigemptyset (&top_level_mask);
292   sigprocmask (SIG_BLOCK, (sigset_t *)NULL, &top_level_mask);
293 #  if defined (SIGCHLD)
294   sigdelset (&top_level_mask, SIGCHLD);
295 #  endif
296 #endif /* JOB_CONTROL || HAVE_POSIX_SIGNALS */
297
298   /* And, some signals that are specifically ignored by the shell. */
299   set_signal_handler (SIGQUIT, SIG_IGN);
300
301   if (interactive)
302     {
303       set_signal_handler (SIGINT, sigint_sighandler);
304       set_signal_handler (SIGTERM, SIG_IGN);
305       set_sigwinch_handler ();
306     }
307 }
308
309 void
310 reset_terminating_signals ()
311 {
312   register int i;
313 #if defined (HAVE_POSIX_SIGNALS)
314   struct sigaction act;
315 #endif
316
317   if (termsigs_initialized == 0)
318     return;
319
320 #if defined (HAVE_POSIX_SIGNALS)
321   act.sa_flags = 0;
322   sigemptyset (&act.sa_mask);
323   for (i = 0; i < TERMSIGS_LENGTH; i++)
324     {
325       /* Skip a signal if it's trapped or handled specially, because the
326          trap code will restore the correct value. */
327       if (signal_is_trapped (XSIG (i)) || signal_is_special (XSIG (i)))
328         continue;
329
330       act.sa_handler = XHANDLER (i);
331       act.sa_flags = XSAFLAGS (i);
332       sigaction (XSIG (i), &act, (struct sigaction *) NULL);
333     }
334 #else /* !HAVE_POSIX_SIGNALS */
335   for (i = 0; i < TERMSIGS_LENGTH; i++)
336     {
337       if (signal_is_trapped (XSIG (i)) || signal_is_special (XSIG (i)))
338         continue;
339
340       signal (XSIG (i), XHANDLER (i));
341     }
342 #endif /* !HAVE_POSIX_SIGNALS */
343 }
344 #undef XSIG
345 #undef XHANDLER
346
347 /* What to do when we've been interrupted, and it is safe to handle it. */
348 void
349 throw_to_top_level ()
350 {
351   int print_newline = 0;
352
353   if (interrupt_state)
354     {
355       print_newline = 1;
356       DELINTERRUPT;
357     }
358
359   if (interrupt_state)
360     return;
361
362   last_command_exit_signal = (last_command_exit_value > 128) ?
363                                 (last_command_exit_value - 128) : 0;
364   last_command_exit_value |= 128;
365
366   /* Run any traps set on SIGINT. */
367   run_interrupt_trap ();
368
369   /* Cleanup string parser environment. */
370   while (parse_and_execute_level)
371     parse_and_execute_cleanup ();
372
373 #if defined (JOB_CONTROL)
374   give_terminal_to (shell_pgrp, 0);
375 #endif /* JOB_CONTROL */
376
377 #if defined (JOB_CONTROL) || defined (HAVE_POSIX_SIGNALS)
378   /* This should not be necessary on systems using sigsetjmp/siglongjmp. */
379   sigprocmask (SIG_SETMASK, &top_level_mask, (sigset_t *)NULL);
380 #endif
381
382   reset_parser ();
383
384 #if defined (READLINE)
385   if (interactive)
386     bashline_reinitialize ();
387 #endif /* READLINE */
388
389 #if defined (PROCESS_SUBSTITUTION)
390   unlink_fifo_list ();
391 #endif /* PROCESS_SUBSTITUTION */
392
393   run_unwind_protects ();
394   loop_level = continuing = breaking = 0;
395   return_catch_flag = 0;
396
397   if (interactive && print_newline)
398     {
399       fflush (stdout);
400       fprintf (stderr, "\n");
401       fflush (stderr);
402     }
403
404   /* An interrupted `wait' command in a script does not exit the script. */
405   if (interactive || (interactive_shell && !shell_initialized) ||
406       (print_newline && signal_is_trapped (SIGINT)))
407     jump_to_top_level (DISCARD);
408   else
409     jump_to_top_level (EXITPROG);
410 }
411
412 /* This is just here to isolate the longjmp calls. */
413 void
414 jump_to_top_level (value)
415      int value;
416 {
417   longjmp (top_level, value);
418 }
419
420 sighandler
421 termination_unwind_protect (sig)
422      int sig;
423 {
424   /* I don't believe this condition ever tests true. */
425   if (sig == SIGINT && signal_is_trapped (SIGINT))
426     run_interrupt_trap ();
427
428 #if defined (HISTORY)
429   /* This might be unsafe, since it eventually calls functions POSIX says
430      not to call from signal handlers.  If it's a problem, take this code
431      out. */
432   if (interactive_shell && sig != SIGABRT)
433     maybe_save_shell_history ();
434 #endif /* HISTORY */
435
436 #if defined (JOB_CONTROL)
437   if (interactive && sig == SIGHUP)
438     hangup_all_jobs ();
439   end_job_control ();
440 #endif /* JOB_CONTROL */
441
442 #if defined (PROCESS_SUBSTITUTION)
443   unlink_fifo_list ();
444 #endif /* PROCESS_SUBSTITUTION */
445
446   run_exit_trap ();
447   set_signal_handler (sig, SIG_DFL);
448   kill (getpid (), sig);
449
450   SIGRETURN (0);
451 }
452
453 /* What we really do when SIGINT occurs. */
454 sighandler
455 sigint_sighandler (sig)
456      int sig;
457 {
458 #if defined (MUST_REINSTALL_SIGHANDLERS)
459   signal (sig, sigint_sighandler);
460 #endif
461
462   /* interrupt_state needs to be set for the stack of interrupts to work
463      right.  Should it be set unconditionally? */
464   if (interrupt_state == 0)
465     ADDINTERRUPT;
466
467   if (interrupt_immediately)
468     {
469       interrupt_immediately = 0;
470       throw_to_top_level ();
471     }
472
473   SIGRETURN (0);
474 }
475
476 #if defined (SIGWINCH)
477 sighandler
478 sigwinch_sighandler (sig)
479      int sig;
480 {
481 #if defined (MUST_REINSTALL_SIGHANDLERS)
482   set_signal_handler (SIGWINCH, sigwinch_sighandler);
483 #endif /* MUST_REINSTALL_SIGHANDLERS */
484   sigwinch_received = 1;
485   SIGRETURN (0);
486 }
487 #endif /* SIGWINCH */
488
489 void
490 set_sigwinch_handler ()
491 {
492 #if defined (SIGWINCH)
493  old_winch = set_signal_handler (SIGWINCH, sigwinch_sighandler);
494 #endif
495 }
496
497 void
498 unset_sigwinch_handler ()
499 {
500 #if defined (SIGWINCH)
501   set_signal_handler (SIGWINCH, old_winch);
502 #endif
503 }
504
505 /* Signal functions used by the rest of the code. */
506 #if !defined (HAVE_POSIX_SIGNALS)
507
508 #if defined (JOB_CONTROL)
509 /* Perform OPERATION on NEWSET, perhaps leaving information in OLDSET. */
510 sigprocmask (operation, newset, oldset)
511      int operation, *newset, *oldset;
512 {
513   int old, new;
514
515   if (newset)
516     new = *newset;
517   else
518     new = 0;
519
520   switch (operation)
521     {
522     case SIG_BLOCK:
523       old = sigblock (new);
524       break;
525
526     case SIG_SETMASK:
527       sigsetmask (new);
528       break;
529
530     default:
531       internal_error (_("sigprocmask: %d: invalid operation"), operation);
532     }
533
534   if (oldset)
535     *oldset = old;
536 }
537 #endif /* JOB_CONTROL */
538
539 #else
540
541 #if !defined (SA_INTERRUPT)
542 #  define SA_INTERRUPT 0
543 #endif
544
545 #if !defined (SA_RESTART)
546 #  define SA_RESTART 0
547 #endif
548
549 SigHandler *
550 set_signal_handler (sig, handler)
551      int sig;
552      SigHandler *handler;
553 {
554   struct sigaction act, oact;
555
556   act.sa_handler = handler;
557   act.sa_flags = 0;
558 #if 0
559   if (sig == SIGALRM)
560     act.sa_flags |= SA_INTERRUPT;       /* XXX */
561   else
562     act.sa_flags |= SA_RESTART;         /* XXX */
563 #endif
564   sigemptyset (&act.sa_mask);
565   sigemptyset (&oact.sa_mask);
566   sigaction (sig, &act, &oact);
567   return (oact.sa_handler);
568 }
569 #endif /* HAVE_POSIX_SIGNALS */