Bash-4.2 distribution sources and documentation
[platform/upstream/bash.git] / trap.c
1 /* trap.c -- Not the trap command, but useful functions for manipulating
2    those objects.  The trap command is in builtins/trap.def. */
3
4 /* Copyright (C) 1987-2010 Free Software Foundation, Inc.
5
6    This file is part of GNU Bash, the Bourne Again SHell.
7
8    Bash is free software: you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation, either version 3 of the License, or
11    (at your option) any later version.
12
13    Bash is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with Bash.  If not, see <http://www.gnu.org/licenses/>.
20 */
21
22 #include "config.h"
23
24 #if defined (HAVE_UNISTD_H)
25 #  include <unistd.h>
26 #endif
27
28 #include "bashtypes.h"
29 #include "bashansi.h"
30
31 #include <stdio.h>
32 #include <errno.h>
33
34 #include "bashintl.h"
35
36 #include "trap.h"
37
38 #include "shell.h"
39 #include "flags.h"
40 #include "input.h"      /* for save_token_state, restore_token_state */
41 #include "jobs.h"
42 #include "signames.h"
43 #include "builtins.h"
44 #include "builtins/common.h"
45 #include "builtins/builtext.h"
46
47 #ifndef errno
48 extern int errno;
49 #endif
50
51 /* Flags which describe the current handling state of a signal. */
52 #define SIG_INHERITED   0x0     /* Value inherited from parent. */
53 #define SIG_TRAPPED     0x1     /* Currently trapped. */
54 #define SIG_HARD_IGNORE 0x2     /* Signal was ignored on shell entry. */
55 #define SIG_SPECIAL     0x4     /* Treat this signal specially. */
56 #define SIG_NO_TRAP     0x8     /* Signal cannot be trapped. */
57 #define SIG_INPROGRESS  0x10    /* Signal handler currently executing. */
58 #define SIG_CHANGED     0x20    /* Trap value changed in trap handler. */
59 #define SIG_IGNORED     0x40    /* The signal is currently being ignored. */
60
61 #define SPECIAL_TRAP(s) ((s) == EXIT_TRAP || (s) == DEBUG_TRAP || (s) == ERROR_TRAP || (s) == RETURN_TRAP)
62
63 /* An array of such flags, one for each signal, describing what the
64    shell will do with a signal.  DEBUG_TRAP == NSIG; some code below
65    assumes this. */
66 static int sigmodes[BASH_NSIG];
67
68 static void free_trap_command __P((int));
69 static void change_signal __P((int, char *));
70
71 static void get_original_signal __P((int));
72
73 static int _run_trap_internal __P((int, char *));
74
75 static void free_trap_string __P((int));
76 static void reset_signal __P((int));
77 static void restore_signal __P((int));
78 static void reset_or_restore_signal_handlers __P((sh_resetsig_func_t *));
79
80 /* Variables used here but defined in other files. */
81 extern int last_command_exit_value;
82 extern int line_number;
83
84 extern char *this_command_name;
85 extern sh_builtin_func_t *this_shell_builtin;
86 extern procenv_t wait_intr_buf;
87 extern int return_catch_flag, return_catch_value;
88 extern int subshell_level;
89 extern WORD_LIST *subst_assign_varlist;
90
91 /* The list of things to do originally, before we started trapping. */
92 SigHandler *original_signals[NSIG];
93
94 /* For each signal, a slot for a string, which is a command to be
95    executed when that signal is recieved.  The slot can also contain
96    DEFAULT_SIG, which means do whatever you were going to do before
97    you were so rudely interrupted, or IGNORE_SIG, which says ignore
98    this signal. */
99 char *trap_list[BASH_NSIG];
100
101 /* A bitmap of signals received for which we have trap handlers. */
102 int pending_traps[NSIG];
103
104 /* Set to the number of the signal we're running the trap for + 1.
105    Used in execute_cmd.c and builtins/common.c to clean up when
106    parse_and_execute does not return normally after executing the
107    trap command (e.g., when `return' is executed in the trap command). */
108 int running_trap;
109
110 /* Set to last_command_exit_value before running a trap. */
111 int trap_saved_exit_value;
112
113 /* The (trapped) signal received while executing in the `wait' builtin */
114 int wait_signal_received;
115
116 #define GETORIGSIG(sig) \
117   do { \
118     original_signals[sig] = (SigHandler *)set_signal_handler (sig, SIG_DFL); \
119     set_signal_handler (sig, original_signals[sig]); \
120     if (original_signals[sig] == SIG_IGN) \
121       sigmodes[sig] |= SIG_HARD_IGNORE; \
122   } while (0)
123
124 #define SETORIGSIG(sig,handler) \
125   do { \
126     original_signals[sig] = handler; \
127     if (original_signals[sig] == SIG_IGN) \
128       sigmodes[sig] |= SIG_HARD_IGNORE; \
129   } while (0)
130
131 #define GET_ORIGINAL_SIGNAL(sig) \
132   if (sig && sig < NSIG && original_signals[sig] == IMPOSSIBLE_TRAP_HANDLER) \
133     GETORIGSIG(sig)
134
135 void
136 initialize_traps ()
137 {
138   register int i;
139
140   initialize_signames();
141
142   trap_list[EXIT_TRAP] = trap_list[DEBUG_TRAP] = trap_list[ERROR_TRAP] = trap_list[RETURN_TRAP] = (char *)NULL;
143   sigmodes[EXIT_TRAP] = sigmodes[DEBUG_TRAP] = sigmodes[ERROR_TRAP] = sigmodes[RETURN_TRAP] = SIG_INHERITED;
144   original_signals[EXIT_TRAP] = IMPOSSIBLE_TRAP_HANDLER;
145
146   for (i = 1; i < NSIG; i++)
147     {
148       pending_traps[i] = 0;
149       trap_list[i] = (char *)DEFAULT_SIG;
150       sigmodes[i] = SIG_INHERITED;      /* XXX - only set, not used */
151       original_signals[i] = IMPOSSIBLE_TRAP_HANDLER;
152     }
153
154   /* Show which signals are treated specially by the shell. */
155 #if defined (SIGCHLD)
156   GETORIGSIG (SIGCHLD);
157   sigmodes[SIGCHLD] |= (SIG_SPECIAL | SIG_NO_TRAP);
158 #endif /* SIGCHLD */
159
160   GETORIGSIG (SIGINT);
161   sigmodes[SIGINT] |= SIG_SPECIAL;
162
163 #if defined (__BEOS__)
164   /* BeOS sets SIGINT to SIG_IGN! */
165   original_signals[SIGINT] = SIG_DFL;
166   sigmodes[SIGINT] &= ~SIG_HARD_IGNORE;
167 #endif
168
169   GETORIGSIG (SIGQUIT);
170   sigmodes[SIGQUIT] |= SIG_SPECIAL;
171
172   if (interactive)
173     {
174       GETORIGSIG (SIGTERM);
175       sigmodes[SIGTERM] |= SIG_SPECIAL;
176     }
177 }
178
179 #ifdef INCLUDE_UNUSED
180 /* Return a printable representation of the trap handler for SIG. */
181 static char *
182 trap_handler_string (sig)
183      int sig;
184 {
185   if (trap_list[sig] == (char *)DEFAULT_SIG)
186     return "DEFAULT_SIG";
187   else if (trap_list[sig] == (char *)IGNORE_SIG)
188     return "IGNORE_SIG";
189   else if (trap_list[sig] == (char *)IMPOSSIBLE_TRAP_HANDLER)
190     return "IMPOSSIBLE_TRAP_HANDLER";
191   else if (trap_list[sig])
192     return trap_list[sig];
193   else
194     return "NULL";
195 }
196 #endif
197
198 /* Return the print name of this signal. */
199 char *
200 signal_name (sig)
201      int sig;
202 {
203   char *ret;
204
205   /* on cygwin32, signal_names[sig] could be null */
206   ret = (sig >= BASH_NSIG || sig < 0 || signal_names[sig] == NULL)
207         ? _("invalid signal number")
208         : signal_names[sig];
209
210   return ret;
211 }
212
213 /* Turn a string into a signal number, or a number into
214    a signal number.  If STRING is "2", "SIGINT", or "INT",
215    then (int)2 is returned.  Return NO_SIG if STRING doesn't
216    contain a valid signal descriptor. */
217 int
218 decode_signal (string, flags)
219      char *string;
220      int flags;
221 {
222   intmax_t sig;
223   char *name;
224
225   if (legal_number (string, &sig))
226     return ((sig >= 0 && sig < NSIG) ? (int)sig : NO_SIG);
227
228   /* A leading `SIG' may be omitted. */
229   for (sig = 0; sig < BASH_NSIG; sig++)
230     {
231       name = signal_names[sig];
232       if (name == 0 || name[0] == '\0')
233         continue;
234
235       /* Check name without the SIG prefix first case sensitivly or
236          insensitively depending on whether flags includes DSIG_NOCASE */
237       if (STREQN (name, "SIG", 3))
238         {
239           name += 3;
240
241           if ((flags & DSIG_NOCASE) && strcasecmp (string, name) == 0)
242             return ((int)sig);
243           else if ((flags & DSIG_NOCASE) == 0 && strcmp (string, name) == 0)
244             return ((int)sig);
245           /* If we can't use the `SIG' prefix to match, punt on this
246              name now. */
247           else if ((flags & DSIG_SIGPREFIX) == 0)
248             continue;
249         }
250
251       /* Check name with SIG prefix case sensitively or insensitively
252          depending on whether flags includes DSIG_NOCASE */
253       name = signal_names[sig];
254       if ((flags & DSIG_NOCASE) && strcasecmp (string, name) == 0)
255         return ((int)sig);
256       else if ((flags & DSIG_NOCASE) == 0 && strcmp (string, name) == 0)
257         return ((int)sig);
258     }
259
260   return (NO_SIG);
261 }
262
263 /* Non-zero when we catch a trapped signal. */
264 static int catch_flag;
265
266 void
267 run_pending_traps ()
268 {
269   register int sig;
270   int old_exit_value, *token_state;
271   WORD_LIST *save_subst_varlist;
272 #if defined (ARRAY_VARS)
273   ARRAY *ps;
274 #endif
275
276   if (catch_flag == 0)          /* simple optimization */
277     return;
278
279   catch_flag = 0;
280
281   /* Preserve $? when running trap. */
282   old_exit_value = last_command_exit_value;
283 #if defined (ARRAY_VARS)
284   ps = save_pipestatus_array ();
285 #endif
286
287   for (sig = 1; sig < NSIG; sig++)
288     {
289       /* XXX this could be made into a counter by using
290          while (pending_traps[sig]--) instead of the if statement. */
291       if (pending_traps[sig])
292         {
293 #if defined (HAVE_POSIX_SIGNALS)
294           sigset_t set, oset;
295
296           sigemptyset (&set);
297           sigemptyset (&oset);
298
299           sigaddset (&set, sig);
300           sigprocmask (SIG_BLOCK, &set, &oset);
301 #else
302 #  if defined (HAVE_BSD_SIGNALS)
303           int oldmask = sigblock (sigmask (sig));
304 #  endif
305 #endif /* HAVE_POSIX_SIGNALS */
306
307           if (sig == SIGINT)
308             {
309               run_interrupt_trap ();
310               CLRINTERRUPT;
311             }
312 #if defined (JOB_CONTROL) && defined (SIGCHLD)
313           else if (sig == SIGCHLD &&
314                    trap_list[SIGCHLD] != (char *)IMPOSSIBLE_TRAP_HANDLER &&
315                    (sigmodes[SIGCHLD] & SIG_INPROGRESS) == 0)
316             {
317               run_sigchld_trap (pending_traps[sig]);    /* use as counter */
318             }
319 #endif
320           else if (trap_list[sig] == (char *)DEFAULT_SIG ||
321                    trap_list[sig] == (char *)IGNORE_SIG ||
322                    trap_list[sig] == (char *)IMPOSSIBLE_TRAP_HANDLER)
323             {
324               /* This is possible due to a race condition.  Say a bash
325                  process has SIGTERM trapped.  A subshell is spawned
326                  using { list; } & and the parent does something and kills
327                  the subshell with SIGTERM.  It's possible for the subshell
328                  to set pending_traps[SIGTERM] to 1 before the code in
329                  execute_cmd.c eventually calls restore_original_signals
330                  to reset the SIGTERM signal handler in the subshell.  The
331                  next time run_pending_traps is called, pending_traps[SIGTERM]
332                  will be 1, but the trap handler in trap_list[SIGTERM] will
333                  be invalid (probably DEFAULT_SIG, but it could be IGNORE_SIG).
334                  Unless we catch this, the subshell will dump core when
335                  trap_list[SIGTERM] == DEFAULT_SIG, because DEFAULT_SIG is
336                  usually 0x0. */
337               internal_warning (_("run_pending_traps: bad value in trap_list[%d]: %p"),
338                                 sig, trap_list[sig]);
339               if (trap_list[sig] == (char *)DEFAULT_SIG)
340                 {
341                   internal_warning (_("run_pending_traps: signal handler is SIG_DFL, resending %d (%s) to myself"), sig, signal_name (sig));
342                   kill (getpid (), sig);
343                 }
344             }
345           else
346             {
347               token_state = save_token_state ();
348               save_subst_varlist = subst_assign_varlist;
349               subst_assign_varlist = 0;
350
351               parse_and_execute (savestring (trap_list[sig]), "trap", SEVAL_NONINT|SEVAL_NOHIST|SEVAL_RESETLINE);
352               restore_token_state (token_state);
353               free (token_state);
354
355               subst_assign_varlist = save_subst_varlist;
356             }
357
358           pending_traps[sig] = 0;
359
360 #if defined (HAVE_POSIX_SIGNALS)
361           sigprocmask (SIG_SETMASK, &oset, (sigset_t *)NULL);
362 #else
363 #  if defined (HAVE_BSD_SIGNALS)
364           sigsetmask (oldmask);
365 #  endif
366 #endif /* POSIX_VERSION */
367         }
368     }
369
370 #if defined (ARRAY_VARS)
371   restore_pipestatus_array (ps);
372 #endif
373   last_command_exit_value = old_exit_value;
374 }
375
376 sighandler
377 trap_handler (sig)
378      int sig;
379 {
380   int oerrno;
381
382   if ((sigmodes[sig] & SIG_TRAPPED) == 0)
383     {
384 #if defined (DEBUG)
385       internal_warning ("trap_handler: signal %d: signal not trapped", sig);
386 #endif
387       SIGRETURN (0);
388     }
389
390   if ((sig >= NSIG) ||
391       (trap_list[sig] == (char *)DEFAULT_SIG) ||
392       (trap_list[sig] == (char *)IGNORE_SIG))
393     programming_error (_("trap_handler: bad signal %d"), sig);
394   else
395     {
396       oerrno = errno;
397 #if defined (MUST_REINSTALL_SIGHANDLERS)
398 #  if defined (JOB_CONTROL) && defined (SIGCHLD)
399       if (sig != SIGCHLD)
400 #  endif /* JOB_CONTROL && SIGCHLD */
401       set_signal_handler (sig, trap_handler);
402 #endif /* MUST_REINSTALL_SIGHANDLERS */
403
404       catch_flag = 1;
405       pending_traps[sig]++;
406
407       if (interrupt_immediately && this_shell_builtin && (this_shell_builtin == wait_builtin))
408         {
409           wait_signal_received = sig;
410           longjmp (wait_intr_buf, 1);
411         }
412
413       if (interrupt_immediately)
414         run_pending_traps ();
415
416       errno = oerrno;
417     }
418
419   SIGRETURN (0);
420 }
421
422 #if defined (JOB_CONTROL) && defined (SIGCHLD)
423
424 #ifdef INCLUDE_UNUSED
425 /* Make COMMAND_STRING be executed when SIGCHLD is caught. */
426 void
427 set_sigchld_trap (command_string)
428      char *command_string;
429 {
430   set_signal (SIGCHLD, command_string);
431 }
432 #endif
433
434 /* Make COMMAND_STRING be executed when SIGCHLD is caught iff SIGCHLD
435    is not already trapped.  IMPOSSIBLE_TRAP_HANDLER is used as a sentinel
436    to make sure that a SIGCHLD trap handler run via run_sigchld_trap can
437    reset the disposition to the default and not have the original signal
438    accidentally restored, undoing the user's command. */
439 void
440 maybe_set_sigchld_trap (command_string)
441      char *command_string;
442 {
443   if ((sigmodes[SIGCHLD] & SIG_TRAPPED) == 0 && trap_list[SIGCHLD] == (char *)IMPOSSIBLE_TRAP_HANDLER)
444     set_signal (SIGCHLD, command_string);
445 }
446
447 /* Temporarily set the SIGCHLD trap string to IMPOSSIBLE_TRAP_HANDLER.  Used
448    as a sentinel in run_sigchld_trap and maybe_set_sigchld_trap to see whether
449    or not a SIGCHLD trap handler reset SIGCHLD disposition to the default. */
450 void
451 set_impossible_sigchld_trap ()
452 {
453   restore_default_signal (SIGCHLD);
454   change_signal (SIGCHLD, (char *)IMPOSSIBLE_TRAP_HANDLER);
455   sigmodes[SIGCHLD] &= ~SIG_TRAPPED;    /* maybe_set_sigchld_trap checks this */
456 }
457 #endif /* JOB_CONTROL && SIGCHLD */
458
459 void
460 set_debug_trap (command)
461      char *command;
462 {
463   set_signal (DEBUG_TRAP, command);
464 }
465
466 void
467 set_error_trap (command)
468      char *command;
469 {
470   set_signal (ERROR_TRAP, command);
471 }
472
473 void
474 set_return_trap (command)
475      char *command;
476 {
477   set_signal (RETURN_TRAP, command);
478 }
479
480 #ifdef INCLUDE_UNUSED
481 void
482 set_sigint_trap (command)
483      char *command;
484 {
485   set_signal (SIGINT, command);
486 }
487 #endif
488
489 /* Reset the SIGINT handler so that subshells that are doing `shellsy'
490    things, like waiting for command substitution or executing commands
491    in explicit subshells ( ( cmd ) ), can catch interrupts properly. */
492 SigHandler *
493 set_sigint_handler ()
494 {
495   if (sigmodes[SIGINT] & SIG_HARD_IGNORE)
496     return ((SigHandler *)SIG_IGN);
497
498   else if (sigmodes[SIGINT] & SIG_IGNORED)
499     return ((SigHandler *)set_signal_handler (SIGINT, SIG_IGN)); /* XXX */
500
501   else if (sigmodes[SIGINT] & SIG_TRAPPED)
502     return ((SigHandler *)set_signal_handler (SIGINT, trap_handler));
503
504   /* The signal is not trapped, so set the handler to the shell's special
505      interrupt handler. */
506   else if (interactive) /* XXX - was interactive_shell */
507     return (set_signal_handler (SIGINT, sigint_sighandler));
508   else
509     return (set_signal_handler (SIGINT, termsig_sighandler));
510 }
511
512 /* Return the correct handler for signal SIG according to the values in
513    sigmodes[SIG]. */
514 SigHandler *
515 trap_to_sighandler (sig)
516      int sig;
517 {
518   if (sigmodes[sig] & (SIG_IGNORED|SIG_HARD_IGNORE))
519     return (SIG_IGN);
520   else if (sigmodes[sig] & SIG_TRAPPED)
521     return (trap_handler);
522   else
523     return (SIG_DFL);
524 }
525
526 /* Set SIG to call STRING as a command. */
527 void
528 set_signal (sig, string)
529      int sig;
530      char *string;
531 {
532   if (SPECIAL_TRAP (sig))
533     {
534       change_signal (sig, savestring (string));
535       if (sig == EXIT_TRAP && interactive == 0)
536         initialize_terminating_signals ();
537       return;
538     }
539
540   /* A signal ignored on entry to the shell cannot be trapped or reset, but
541      no error is reported when attempting to do so.  -- Posix.2 */
542   if (sigmodes[sig] & SIG_HARD_IGNORE)
543     return;
544
545   /* Make sure we have original_signals[sig] if the signal has not yet
546      been trapped. */
547   if ((sigmodes[sig] & SIG_TRAPPED) == 0)
548     {
549       /* If we aren't sure of the original value, check it. */
550       if (original_signals[sig] == IMPOSSIBLE_TRAP_HANDLER)
551         GETORIGSIG (sig);
552       if (original_signals[sig] == SIG_IGN)
553         return;
554     }
555
556   /* Only change the system signal handler if SIG_NO_TRAP is not set.
557      The trap command string is changed in either case.  The shell signal
558      handlers for SIGINT and SIGCHLD run the user specified traps in an
559      environment in which it is safe to do so. */
560   if ((sigmodes[sig] & SIG_NO_TRAP) == 0)
561     {
562       set_signal_handler (sig, SIG_IGN);
563       change_signal (sig, savestring (string));
564       set_signal_handler (sig, trap_handler);
565     }
566   else
567     change_signal (sig, savestring (string));
568 }
569
570 static void
571 free_trap_command (sig)
572      int sig;
573 {
574   if ((sigmodes[sig] & SIG_TRAPPED) && trap_list[sig] &&
575       (trap_list[sig] != (char *)IGNORE_SIG) &&
576       (trap_list[sig] != (char *)DEFAULT_SIG) &&
577       (trap_list[sig] != (char *)IMPOSSIBLE_TRAP_HANDLER))
578     free (trap_list[sig]);
579 }
580
581 /* If SIG has a string assigned to it, get rid of it.  Then give it
582    VALUE. */
583 static void
584 change_signal (sig, value)
585      int sig;
586      char *value;
587 {
588   if ((sigmodes[sig] & SIG_INPROGRESS) == 0)
589     free_trap_command (sig);
590   trap_list[sig] = value;
591
592   sigmodes[sig] |= SIG_TRAPPED;
593   if (value == (char *)IGNORE_SIG)
594     sigmodes[sig] |= SIG_IGNORED;
595   else
596     sigmodes[sig] &= ~SIG_IGNORED;
597   if (sigmodes[sig] & SIG_INPROGRESS)
598     sigmodes[sig] |= SIG_CHANGED;
599 }
600
601 static void
602 get_original_signal (sig)
603      int sig;
604 {
605   /* If we aren't sure the of the original value, then get it. */
606   if (sig > 0 && sig < NSIG && original_signals[sig] == (SigHandler *)IMPOSSIBLE_TRAP_HANDLER)
607     GETORIGSIG (sig);
608 }
609
610 void
611 get_all_original_signals ()
612 {
613   register int i;
614
615   for (i = 1; i < NSIG; i++)
616     GET_ORIGINAL_SIGNAL (i);
617 }
618
619 void
620 set_original_signal (sig, handler)
621      int sig;
622      SigHandler *handler;
623 {
624   if (sig > 0 && sig < NSIG && original_signals[sig] == (SigHandler *)IMPOSSIBLE_TRAP_HANDLER)
625     SETORIGSIG (sig, handler);
626 }
627
628 /* Restore the default action for SIG; i.e., the action the shell
629    would have taken before you used the trap command.  This is called
630    from trap_builtin (), which takes care to restore the handlers for
631    the signals the shell treats specially. */
632 void
633 restore_default_signal (sig)
634      int sig;
635 {
636   if (SPECIAL_TRAP (sig))
637     {
638       if ((sig != DEBUG_TRAP && sig != ERROR_TRAP && sig != RETURN_TRAP) ||
639           (sigmodes[sig] & SIG_INPROGRESS) == 0)
640         free_trap_command (sig);
641       trap_list[sig] = (char *)NULL;
642       sigmodes[sig] &= ~SIG_TRAPPED;
643       if (sigmodes[sig] & SIG_INPROGRESS)
644         sigmodes[sig] |= SIG_CHANGED;
645       return;
646     }
647
648   GET_ORIGINAL_SIGNAL (sig);
649
650   /* A signal ignored on entry to the shell cannot be trapped or reset, but
651      no error is reported when attempting to do so.  Thanks Posix.2. */
652   if (sigmodes[sig] & SIG_HARD_IGNORE)
653     return;
654
655   /* If we aren't trapping this signal, don't bother doing anything else. */
656   if ((sigmodes[sig] & SIG_TRAPPED) == 0)
657     return;
658
659   /* Only change the signal handler for SIG if it allows it. */
660   if ((sigmodes[sig] & SIG_NO_TRAP) == 0)
661     set_signal_handler (sig, original_signals[sig]);
662
663   /* Change the trap command in either case. */
664   change_signal (sig, (char *)DEFAULT_SIG);
665
666   /* Mark the signal as no longer trapped. */
667   sigmodes[sig] &= ~SIG_TRAPPED;
668 }
669
670 /* Make this signal be ignored. */
671 void
672 ignore_signal (sig)
673      int sig;
674 {
675   if (SPECIAL_TRAP (sig) && ((sigmodes[sig] & SIG_IGNORED) == 0))
676     {
677       change_signal (sig, (char *)IGNORE_SIG);
678       return;
679     }
680
681   GET_ORIGINAL_SIGNAL (sig);
682
683   /* A signal ignored on entry to the shell cannot be trapped or reset.
684      No error is reported when the user attempts to do so. */
685   if (sigmodes[sig] & SIG_HARD_IGNORE)
686     return;
687
688   /* If already trapped and ignored, no change necessary. */
689   if (sigmodes[sig] & SIG_IGNORED)
690     return;
691
692   /* Only change the signal handler for SIG if it allows it. */
693   if ((sigmodes[sig] & SIG_NO_TRAP) == 0)
694     set_signal_handler (sig, SIG_IGN);
695
696   /* Change the trap command in either case. */
697   change_signal (sig, (char *)IGNORE_SIG);
698 }
699
700 /* Handle the calling of "trap 0".  The only sticky situation is when
701    the command to be executed includes an "exit".  This is why we have
702    to provide our own place for top_level to jump to. */
703 int
704 run_exit_trap ()
705 {
706   char *trap_command;
707   int code, function_code, retval;
708 #if defined (ARRAY_VARS)
709   ARRAY *ps;
710 #endif
711
712   trap_saved_exit_value = last_command_exit_value;
713 #if defined (ARRAY_VARS)
714   ps = save_pipestatus_array ();
715 #endif
716   function_code = 0;
717
718   /* Run the trap only if signal 0 is trapped and not ignored, and we are not
719      currently running in the trap handler (call to exit in the list of
720      commands given to trap 0). */
721   if ((sigmodes[EXIT_TRAP] & SIG_TRAPPED) &&
722       (sigmodes[EXIT_TRAP] & (SIG_IGNORED|SIG_INPROGRESS)) == 0)
723     {
724       trap_command = savestring (trap_list[EXIT_TRAP]);
725       sigmodes[EXIT_TRAP] &= ~SIG_TRAPPED;
726       sigmodes[EXIT_TRAP] |= SIG_INPROGRESS;
727
728       retval = trap_saved_exit_value;
729       running_trap = 1;
730
731       code = setjmp (top_level);
732
733       /* If we're in a function, make sure return longjmps come here, too. */
734       if (return_catch_flag)
735         function_code = setjmp (return_catch);
736
737       if (code == 0 && function_code == 0)
738         {
739           reset_parser ();
740           parse_and_execute (trap_command, "exit trap", SEVAL_NONINT|SEVAL_NOHIST|SEVAL_RESETLINE);
741         }
742       else if (code == ERREXIT)
743         retval = last_command_exit_value;
744       else if (code == EXITPROG)
745         retval = last_command_exit_value;
746       else if (function_code != 0)
747         retval = return_catch_value;
748       else
749         retval = trap_saved_exit_value;
750
751       running_trap = 0;
752       return retval;
753     }
754
755 #if defined (ARRAY_VARS)
756   restore_pipestatus_array (ps);
757 #endif
758   return (trap_saved_exit_value);
759 }
760
761 void
762 run_trap_cleanup (sig)
763      int sig;
764 {
765   sigmodes[sig] &= ~(SIG_INPROGRESS|SIG_CHANGED);
766 }
767
768 /* Run a trap command for SIG.  SIG is one of the signals the shell treats
769    specially.  Returns the exit status of the executed trap command list. */
770 static int
771 _run_trap_internal (sig, tag)
772      int sig;
773      char *tag;
774 {
775   char *trap_command, *old_trap;
776   int trap_exit_value, *token_state;
777   int save_return_catch_flag, function_code, flags;
778   procenv_t save_return_catch;
779   WORD_LIST *save_subst_varlist;
780 #if defined (ARRAY_VARS)
781   ARRAY *ps;
782 #endif
783
784   trap_exit_value = function_code = 0;
785   /* Run the trap only if SIG is trapped and not ignored, and we are not
786      currently executing in the trap handler. */
787   if ((sigmodes[sig] & SIG_TRAPPED) && ((sigmodes[sig] & SIG_IGNORED) == 0) &&
788       (trap_list[sig] != (char *)IMPOSSIBLE_TRAP_HANDLER) &&
789       ((sigmodes[sig] & SIG_INPROGRESS) == 0))
790     {
791       old_trap = trap_list[sig];
792       sigmodes[sig] |= SIG_INPROGRESS;
793       sigmodes[sig] &= ~SIG_CHANGED;            /* just to be sure */
794       trap_command =  savestring (old_trap);
795
796       running_trap = sig + 1;
797       trap_saved_exit_value = last_command_exit_value;
798 #if defined (ARRAY_VARS)
799       ps = save_pipestatus_array ();
800 #endif
801
802       token_state = save_token_state ();
803       save_subst_varlist = subst_assign_varlist;
804       subst_assign_varlist = 0;
805
806       /* If we're in a function, make sure return longjmps come here, too. */
807       save_return_catch_flag = return_catch_flag;
808       if (return_catch_flag)
809         {
810           COPY_PROCENV (return_catch, save_return_catch);
811           function_code = setjmp (return_catch);
812         }
813
814       flags = SEVAL_NONINT|SEVAL_NOHIST;
815       if (sig != DEBUG_TRAP && sig != RETURN_TRAP && sig != ERROR_TRAP)
816         flags |= SEVAL_RESETLINE;
817       if (function_code == 0)
818         parse_and_execute (trap_command, tag, flags);
819
820       restore_token_state (token_state);
821       free (token_state);
822
823       subst_assign_varlist = save_subst_varlist;
824
825       trap_exit_value = last_command_exit_value;
826       last_command_exit_value = trap_saved_exit_value;
827 #if defined (ARRAY_VARS)
828       restore_pipestatus_array (ps);
829 #endif
830       running_trap = 0;
831
832       sigmodes[sig] &= ~SIG_INPROGRESS;
833
834       if (sigmodes[sig] & SIG_CHANGED)
835         {
836 #if 0
837           /* Special traps like EXIT, DEBUG, RETURN are handled explicitly in
838              the places where they can be changed using unwind-protects.  For
839              example, look at execute_cmd.c:execute_function(). */
840           if (SPECIAL_TRAP (sig) == 0)
841 #endif
842             free (old_trap);
843           sigmodes[sig] &= ~SIG_CHANGED;
844         }
845
846       if (save_return_catch_flag)
847         {
848           return_catch_flag = save_return_catch_flag;
849           return_catch_value = trap_exit_value;
850           COPY_PROCENV (save_return_catch, return_catch);
851           if (function_code)
852             longjmp (return_catch, 1);
853         }
854     }
855
856   return trap_exit_value;
857 }
858
859 int
860 run_debug_trap ()
861 {
862   int trap_exit_value;
863   pid_t save_pgrp;
864   int save_pipe[2];
865
866   /* XXX - question:  should the DEBUG trap inherit the RETURN trap? */
867   trap_exit_value = 0;
868   if ((sigmodes[DEBUG_TRAP] & SIG_TRAPPED) && ((sigmodes[DEBUG_TRAP] & SIG_IGNORED) == 0) && ((sigmodes[DEBUG_TRAP] & SIG_INPROGRESS) == 0))
869     {
870 #if defined (JOB_CONTROL)
871       save_pgrp = pipeline_pgrp;
872       pipeline_pgrp = 0;
873       save_pipeline (1);
874 #  if defined (PGRP_PIPE)
875       save_pgrp_pipe (save_pipe, 1);
876 #  endif
877       stop_making_children ();
878 #endif
879
880       trap_exit_value = _run_trap_internal (DEBUG_TRAP, "debug trap");
881
882 #if defined (JOB_CONTROL)
883       pipeline_pgrp = save_pgrp;
884       restore_pipeline (1);
885 #  if defined (PGRP_PIPE)
886       close_pgrp_pipe ();
887       restore_pgrp_pipe (save_pipe);
888 #  endif
889       if (pipeline_pgrp > 0)
890         give_terminal_to (pipeline_pgrp, 1);
891       notify_and_cleanup ();
892 #endif
893       
894 #if defined (DEBUGGER)
895       /* If we're in the debugger and the DEBUG trap returns 2 while we're in
896          a function or sourced script, we force a `return'. */
897       if (debugging_mode && trap_exit_value == 2 && return_catch_flag)
898         {
899           return_catch_value = trap_exit_value;
900           longjmp (return_catch, 1);
901         }
902 #endif
903     }
904   return trap_exit_value;
905 }
906
907 void
908 run_error_trap ()
909 {
910   if ((sigmodes[ERROR_TRAP] & SIG_TRAPPED) && ((sigmodes[ERROR_TRAP] & SIG_IGNORED) == 0) && (sigmodes[ERROR_TRAP] & SIG_INPROGRESS) == 0)
911     _run_trap_internal (ERROR_TRAP, "error trap");
912 }
913
914 void
915 run_return_trap ()
916 {
917   int old_exit_value;
918
919 #if 0
920   if ((sigmodes[DEBUG_TRAP] & SIG_TRAPPED) && (sigmodes[DEBUG_TRAP] & SIG_INPROGRESS))
921     return;
922 #endif
923
924   if ((sigmodes[RETURN_TRAP] & SIG_TRAPPED) && ((sigmodes[RETURN_TRAP] & SIG_IGNORED) == 0) && (sigmodes[RETURN_TRAP] & SIG_INPROGRESS) == 0)
925     {
926       old_exit_value = last_command_exit_value;
927       _run_trap_internal (RETURN_TRAP, "return trap");
928       last_command_exit_value = old_exit_value;
929     }
930 }
931
932 /* Run a trap set on SIGINT.  This is called from throw_to_top_level (), and
933    declared here to localize the trap functions. */
934 void
935 run_interrupt_trap ()
936 {
937   _run_trap_internal (SIGINT, "interrupt trap");
938 }
939
940 /* Free all the allocated strings in the list of traps and reset the trap
941    values to the default.  Intended to be called from subshells that want
942    to complete work done by reset_signal_handlers upon execution of a
943    subsequent `trap' command that changes a signal's disposition. */
944 void
945 free_trap_strings ()
946 {
947   register int i;
948
949   for (i = 0; i < BASH_NSIG; i++)
950     free_trap_string (i);
951   trap_list[DEBUG_TRAP] = trap_list[EXIT_TRAP] = trap_list[ERROR_TRAP] = trap_list[RETURN_TRAP] = (char *)NULL;
952 }
953
954 /* Free a trap command string associated with SIG without changing signal
955    disposition.  Intended to be called from free_trap_strings()  */
956 static void
957 free_trap_string (sig)
958      int sig;
959 {
960   change_signal (sig, (char *)DEFAULT_SIG);
961   sigmodes[sig] &= ~SIG_TRAPPED;
962 }
963
964 /* Reset the handler for SIG to the original value but leave the trap string
965    in place. */
966 static void
967 reset_signal (sig)
968      int sig;
969 {
970   set_signal_handler (sig, original_signals[sig]);
971   sigmodes[sig] &= ~SIG_TRAPPED;
972 }
973
974 /* Set the handler signal SIG to the original and free any trap
975    command associated with it. */
976 static void
977 restore_signal (sig)
978      int sig;
979 {
980   set_signal_handler (sig, original_signals[sig]);
981   change_signal (sig, (char *)DEFAULT_SIG);
982   sigmodes[sig] &= ~SIG_TRAPPED;
983 }
984
985 static void
986 reset_or_restore_signal_handlers (reset)
987      sh_resetsig_func_t *reset;
988 {
989   register int i;
990
991   /* Take care of the exit trap first */
992   if (sigmodes[EXIT_TRAP] & SIG_TRAPPED)
993     {
994       sigmodes[EXIT_TRAP] &= ~SIG_TRAPPED;
995       if (reset != reset_signal)
996         {
997           free_trap_command (EXIT_TRAP);
998           trap_list[EXIT_TRAP] = (char *)NULL;
999         }
1000     }
1001
1002   for (i = 1; i < NSIG; i++)
1003     {
1004       if (sigmodes[i] & SIG_TRAPPED)
1005         {
1006           if (trap_list[i] == (char *)IGNORE_SIG)
1007             set_signal_handler (i, SIG_IGN);
1008           else
1009             (*reset) (i);
1010         }
1011       else if (sigmodes[i] & SIG_SPECIAL)
1012         (*reset) (i);
1013     }
1014
1015   /* Command substitution and other child processes don't inherit the
1016      debug, error, or return traps.  If we're in the debugger, and the
1017      `functrace' or `errtrace' options have been set, then let command
1018      substitutions inherit them.  Let command substitution inherit the
1019      RETURN trap if we're in the debugger and tracing functions. */
1020   if (function_trace_mode == 0)
1021     {
1022       sigmodes[DEBUG_TRAP] &= ~SIG_TRAPPED;
1023       sigmodes[RETURN_TRAP] &= ~SIG_TRAPPED;
1024     }
1025   if (error_trace_mode == 0)
1026     sigmodes[ERROR_TRAP] &= ~SIG_TRAPPED;
1027 }
1028
1029 /* Reset trapped signals to their original values, but don't free the
1030    trap strings.  Called by the command substitution code and other places
1031    that create a "subshell environment". */
1032 void
1033 reset_signal_handlers ()
1034 {
1035   reset_or_restore_signal_handlers (reset_signal);
1036 }
1037
1038 /* Reset all trapped signals to their original values.  Signals set to be
1039    ignored with trap '' SIGNAL should be ignored, so we make sure that they
1040    are.  Called by child processes after they are forked. */
1041 void
1042 restore_original_signals ()
1043 {
1044   reset_or_restore_signal_handlers (restore_signal);
1045 }
1046
1047 /* If a trap handler exists for signal SIG, then call it; otherwise just
1048    return failure. */
1049 int
1050 maybe_call_trap_handler (sig)
1051      int sig;
1052 {
1053   /* Call the trap handler for SIG if the signal is trapped and not ignored. */
1054   if ((sigmodes[sig] & SIG_TRAPPED) && ((sigmodes[sig] & SIG_IGNORED) == 0))
1055     {
1056       switch (sig)
1057         {
1058         case SIGINT:
1059           run_interrupt_trap ();
1060           break;
1061         case EXIT_TRAP:
1062           run_exit_trap ();
1063           break;
1064         case DEBUG_TRAP:
1065           run_debug_trap ();
1066           break;
1067         case ERROR_TRAP:
1068           run_error_trap ();
1069           break;
1070         default:
1071           trap_handler (sig);
1072           break;
1073         }
1074       return (1);
1075     }
1076   else
1077     return (0);
1078 }
1079
1080 int
1081 signal_is_trapped (sig)
1082      int sig;
1083 {
1084   return (sigmodes[sig] & SIG_TRAPPED);
1085 }
1086
1087 int
1088 signal_is_special (sig)
1089      int sig;
1090 {
1091   return (sigmodes[sig] & SIG_SPECIAL);
1092 }
1093
1094 int
1095 signal_is_ignored (sig)
1096      int sig;
1097 {
1098   return (sigmodes[sig] & SIG_IGNORED);
1099 }
1100
1101 int
1102 signal_is_hard_ignored (sig)
1103      int sig;
1104 {
1105   return (sigmodes[sig] & SIG_HARD_IGNORE);
1106 }
1107
1108 void
1109 set_signal_ignored (sig)
1110      int sig;
1111 {
1112   sigmodes[sig] |= SIG_HARD_IGNORE;
1113   original_signals[sig] = SIG_IGN;
1114 }
1115
1116 int
1117 signal_in_progress (sig)
1118      int sig;
1119 {
1120   return (sigmodes[sig] & SIG_INPROGRESS);
1121 }