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