blob: d1cdedfed156951d786cc238f96898061fe394ed [file] [log] [blame]
Jari Aalto726f6381996-08-26 18:22:31 +00001/* trap.c -- Not the trap command, but useful functions for manipulating
2 those objects. The trap command is in builtins/trap.def. */
3
Chet Rameyac50fba2014-02-26 09:36:43 -05004/* Copyright (C) 1987-2013 Free Software Foundation, Inc.
Jari Aalto726f6381996-08-26 18:22:31 +00005
6 This file is part of GNU Bash, the Bourne Again SHell.
7
Jari Aalto31859422009-01-12 13:36:28 +00008 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.
Jari Aalto726f6381996-08-26 18:22:31 +000012
Jari Aalto31859422009-01-12 13:36:28 +000013 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.
Jari Aalto726f6381996-08-26 18:22:31 +000017
Jari Aalto31859422009-01-12 13:36:28 +000018 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*/
Jari Aalto726f6381996-08-26 18:22:31 +000021
Jari Aaltoccc6cda1996-12-23 17:02:34 +000022#include "config.h"
23
Jari Aaltoe8ce7751997-09-22 20:22:27 +000024#if defined (HAVE_UNISTD_H)
25# include <unistd.h>
26#endif
27
Jari Aalto726f6381996-08-26 18:22:31 +000028#include "bashtypes.h"
Jari Aaltod166f041997-06-05 14:59:13 +000029#include "bashansi.h"
Jari Aalto726f6381996-08-26 18:22:31 +000030
Jari Aaltocce855b1998-04-17 19:52:44 +000031#include <stdio.h>
Jari Aaltobb706242000-03-17 21:46:59 +000032#include <errno.h>
Jari Aaltocce855b1998-04-17 19:52:44 +000033
Jari Aaltob80f6442004-07-27 13:29:18 +000034#include "bashintl.h"
35
Chet Rameyac50fba2014-02-26 09:36:43 -050036#include <signal.h>
37
Jari Aaltocce855b1998-04-17 19:52:44 +000038#include "trap.h"
39
Jari Aalto726f6381996-08-26 18:22:31 +000040#include "shell.h"
Jari Aaltob80f6442004-07-27 13:29:18 +000041#include "flags.h"
Jari Aaltobb706242000-03-17 21:46:59 +000042#include "input.h" /* for save_token_state, restore_token_state */
Jari Aalto31859422009-01-12 13:36:28 +000043#include "jobs.h"
Jari Aalto726f6381996-08-26 18:22:31 +000044#include "signames.h"
Jari Aalto7117c2d2002-07-17 14:10:11 +000045#include "builtins.h"
Jari Aaltoccc6cda1996-12-23 17:02:34 +000046#include "builtins/common.h"
Jari Aalto7117c2d2002-07-17 14:10:11 +000047#include "builtins/builtext.h"
Jari Aalto726f6381996-08-26 18:22:31 +000048
Chet Rameyac50fba2014-02-26 09:36:43 -050049#if defined (READLINE)
50# include <readline/readline.h>
51# include "bashline.h"
52#endif
53
Jari Aaltobb706242000-03-17 21:46:59 +000054#ifndef errno
Ricardo Cerqueiraa02fbff2013-07-25 22:35:34 +010055#include <errno.h>
Jari Aaltobb706242000-03-17 21:46:59 +000056#endif
57
Jari Aalto726f6381996-08-26 18:22:31 +000058/* 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. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +000064#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. */
Jari Aalto726f6381996-08-26 18:22:31 +000067
Jari Aaltob80f6442004-07-27 13:29:18 +000068#define SPECIAL_TRAP(s) ((s) == EXIT_TRAP || (s) == DEBUG_TRAP || (s) == ERROR_TRAP || (s) == RETURN_TRAP)
Jari Aaltof73dda02001-11-13 17:56:06 +000069
Jari Aalto726f6381996-08-26 18:22:31 +000070/* An array of such flags, one for each signal, describing what the
Jari Aaltoccc6cda1996-12-23 17:02:34 +000071 shell will do with a signal. DEBUG_TRAP == NSIG; some code below
72 assumes this. */
Jari Aaltof73dda02001-11-13 17:56:06 +000073static int sigmodes[BASH_NSIG];
Jari Aalto726f6381996-08-26 18:22:31 +000074
Jari Aaltof73dda02001-11-13 17:56:06 +000075static void free_trap_command __P((int));
76static void change_signal __P((int, char *));
77
Jari Aaltob80f6442004-07-27 13:29:18 +000078static int _run_trap_internal __P((int, char *));
Jari Aaltof73dda02001-11-13 17:56:06 +000079
Chet Ramey00018032011-11-21 20:51:19 -050080static void free_trap_string __P((int));
Jari Aaltof73dda02001-11-13 17:56:06 +000081static void reset_signal __P((int));
82static void restore_signal __P((int));
83static void reset_or_restore_signal_handlers __P((sh_resetsig_func_t *));
Jari Aalto726f6381996-08-26 18:22:31 +000084
85/* Variables used here but defined in other files. */
Jari Aalto726f6381996-08-26 18:22:31 +000086extern int last_command_exit_value;
Jari Aaltod166f041997-06-05 14:59:13 +000087extern int line_number;
Jari Aalto726f6381996-08-26 18:22:31 +000088
Chet Rameyac50fba2014-02-26 09:36:43 -050089extern int sigalrm_seen;
90extern procenv_t alrmbuf;
91
Jari Aaltob80f6442004-07-27 13:29:18 +000092extern char *this_command_name;
Jari Aalto7117c2d2002-07-17 14:10:11 +000093extern sh_builtin_func_t *this_shell_builtin;
94extern procenv_t wait_intr_buf;
Jari Aaltob80f6442004-07-27 13:29:18 +000095extern int return_catch_flag, return_catch_value;
96extern int subshell_level;
Chet Ramey00018032011-11-21 20:51:19 -050097extern WORD_LIST *subst_assign_varlist;
Jari Aalto7117c2d2002-07-17 14:10:11 +000098
Jari Aalto726f6381996-08-26 18:22:31 +000099/* The list of things to do originally, before we started trapping. */
100SigHandler *original_signals[NSIG];
101
102/* For each signal, a slot for a string, which is a command to be
Chet Rameyac50fba2014-02-26 09:36:43 -0500103 executed when that signal is received. The slot can also contain
Jari Aalto726f6381996-08-26 18:22:31 +0000104 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. */
Jari Aaltof73dda02001-11-13 17:56:06 +0000107char *trap_list[BASH_NSIG];
Jari Aalto726f6381996-08-26 18:22:31 +0000108
109/* A bitmap of signals received for which we have trap handlers. */
110int pending_traps[NSIG];
111
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000112/* 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). */
116int running_trap;
117
Jari Aaltob80f6442004-07-27 13:29:18 +0000118/* Set to last_command_exit_value before running a trap. */
119int trap_saved_exit_value;
Jari Aaltod166f041997-06-05 14:59:13 +0000120
Jari Aalto7117c2d2002-07-17 14:10:11 +0000121/* The (trapped) signal received while executing in the `wait' builtin */
122int wait_signal_received;
123
Chet Rameyac50fba2014-02-26 09:36:43 -0500124int trapped_signal_received;
125
Jari Aalto06285672006-10-10 14:15:34 +0000126#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
Chet Ramey495aee42011-11-22 19:11:26 -0500134#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
Jari Aalto06285672006-10-10 14:15:34 +0000141#define GET_ORIGINAL_SIGNAL(sig) \
142 if (sig && sig < NSIG && original_signals[sig] == IMPOSSIBLE_TRAP_HANDLER) \
143 GETORIGSIG(sig)
144
Jari Aalto726f6381996-08-26 18:22:31 +0000145void
146initialize_traps ()
147{
148 register int i;
149
Jari Aalto06285672006-10-10 14:15:34 +0000150 initialize_signames();
151
Jari Aaltob80f6442004-07-27 13:29:18 +0000152 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;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000154 original_signals[EXIT_TRAP] = IMPOSSIBLE_TRAP_HANDLER;
Jari Aalto726f6381996-08-26 18:22:31 +0000155
156 for (i = 1; i < NSIG; i++)
157 {
158 pending_traps[i] = 0;
159 trap_list[i] = (char *)DEFAULT_SIG;
Chet Ramey495aee42011-11-22 19:11:26 -0500160 sigmodes[i] = SIG_INHERITED; /* XXX - only set, not used */
Jari Aalto726f6381996-08-26 18:22:31 +0000161 original_signals[i] = IMPOSSIBLE_TRAP_HANDLER;
162 }
163
164 /* Show which signals are treated specially by the shell. */
165#if defined (SIGCHLD)
Jari Aalto06285672006-10-10 14:15:34 +0000166 GETORIGSIG (SIGCHLD);
Jari Aalto726f6381996-08-26 18:22:31 +0000167 sigmodes[SIGCHLD] |= (SIG_SPECIAL | SIG_NO_TRAP);
168#endif /* SIGCHLD */
169
Jari Aalto06285672006-10-10 14:15:34 +0000170 GETORIGSIG (SIGINT);
Jari Aalto726f6381996-08-26 18:22:31 +0000171 sigmodes[SIGINT] |= SIG_SPECIAL;
172
Jari Aaltob72432f1999-02-19 17:11:39 +0000173#if defined (__BEOS__)
174 /* BeOS sets SIGINT to SIG_IGN! */
175 original_signals[SIGINT] = SIG_DFL;
Jari Aalto06285672006-10-10 14:15:34 +0000176 sigmodes[SIGINT] &= ~SIG_HARD_IGNORE;
Jari Aaltob72432f1999-02-19 17:11:39 +0000177#endif
178
Jari Aalto06285672006-10-10 14:15:34 +0000179 GETORIGSIG (SIGQUIT);
Jari Aalto726f6381996-08-26 18:22:31 +0000180 sigmodes[SIGQUIT] |= SIG_SPECIAL;
181
182 if (interactive)
183 {
Jari Aalto06285672006-10-10 14:15:34 +0000184 GETORIGSIG (SIGTERM);
Jari Aalto726f6381996-08-26 18:22:31 +0000185 sigmodes[SIGTERM] |= SIG_SPECIAL;
186 }
187}
188
Chet Rameyac50fba2014-02-26 09:36:43 -0500189#ifdef DEBUG
Jari Aaltobb706242000-03-17 21:46:59 +0000190/* Return a printable representation of the trap handler for SIG. */
191static char *
192trap_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
Jari Aalto726f6381996-08-26 18:22:31 +0000208/* Return the print name of this signal. */
209char *
210signal_name (sig)
211 int sig;
212{
Jari Aaltocce855b1998-04-17 19:52:44 +0000213 char *ret;
214
215 /* on cygwin32, signal_names[sig] could be null */
Jari Aaltob80f6442004-07-27 13:29:18 +0000216 ret = (sig >= BASH_NSIG || sig < 0 || signal_names[sig] == NULL)
217 ? _("invalid signal number")
218 : signal_names[sig];
219
Jari Aaltocce855b1998-04-17 19:52:44 +0000220 return ret;
Jari Aalto726f6381996-08-26 18:22:31 +0000221}
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. */
227int
Jari Aaltob80f6442004-07-27 13:29:18 +0000228decode_signal (string, flags)
Jari Aalto726f6381996-08-26 18:22:31 +0000229 char *string;
Jari Aaltob80f6442004-07-27 13:29:18 +0000230 int flags;
Jari Aalto726f6381996-08-26 18:22:31 +0000231{
Jari Aalto7117c2d2002-07-17 14:10:11 +0000232 intmax_t sig;
Jari Aaltob80f6442004-07-27 13:29:18 +0000233 char *name;
Jari Aalto726f6381996-08-26 18:22:31 +0000234
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000235 if (legal_number (string, &sig))
Jari Aaltof73dda02001-11-13 17:56:06 +0000236 return ((sig >= 0 && sig < NSIG) ? (int)sig : NO_SIG);
Jari Aalto726f6381996-08-26 18:22:31 +0000237
Jari Aaltoe8ce7751997-09-22 20:22:27 +0000238 /* A leading `SIG' may be omitted. */
Jari Aaltof73dda02001-11-13 17:56:06 +0000239 for (sig = 0; sig < BASH_NSIG; sig++)
Jari Aaltob72432f1999-02-19 17:11:39 +0000240 {
Jari Aaltob80f6442004-07-27 13:29:18 +0000241 name = signal_names[sig];
242 if (name == 0 || name[0] == '\0')
Jari Aaltob72432f1999-02-19 17:11:39 +0000243 continue;
Jari Aaltob80f6442004-07-27 13:29:18 +0000244
Chet Rameyac50fba2014-02-26 09:36:43 -0500245 /* Check name without the SIG prefix first case sensitively or
Jari Aaltob80f6442004-07-27 13:29:18 +0000246 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)
Jari Aaltob72432f1999-02-19 17:11:39 +0000267 return ((int)sig);
268 }
Jari Aalto726f6381996-08-26 18:22:31 +0000269
270 return (NO_SIG);
271}
272
273/* Non-zero when we catch a trapped signal. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000274static int catch_flag;
Jari Aalto726f6381996-08-26 18:22:31 +0000275
276void
277run_pending_traps ()
278{
279 register int sig;
Chet Rameyac50fba2014-02-26 09:36:43 -0500280 int old_exit_value;
Chet Ramey00018032011-11-21 20:51:19 -0500281 WORD_LIST *save_subst_varlist;
Chet Rameyac50fba2014-02-26 09:36:43 -0500282 sh_parser_state_t pstate;
Chet Ramey495aee42011-11-22 19:11:26 -0500283#if defined (ARRAY_VARS)
284 ARRAY *ps;
285#endif
Jari Aalto726f6381996-08-26 18:22:31 +0000286
287 if (catch_flag == 0) /* simple optimization */
288 return;
289
Chet Rameyac50fba2014-02-26 09:36:43 -0500290 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;
Jari Aalto726f6381996-08-26 18:22:31 +0000303
304 /* Preserve $? when running trap. */
305 old_exit_value = last_command_exit_value;
Chet Ramey495aee42011-11-22 19:11:26 -0500306#if defined (ARRAY_VARS)
307 ps = save_pipestatus_array ();
308#endif
Jari Aalto726f6381996-08-26 18:22:31 +0000309
310 for (sig = 1; sig < NSIG; sig++)
311 {
312 /* XXX this could be made into a counter by using
Jari Aalto28ef6c32001-04-06 19:14:31 +0000313 while (pending_traps[sig]--) instead of the if statement. */
Jari Aalto726f6381996-08-26 18:22:31 +0000314 if (pending_traps[sig])
315 {
Chet Rameyac50fba2014-02-26 09:36:43 -0500316 if (running_trap == sig+1)
317 /*continue*/;
Jari Aalto726f6381996-08-26 18:22:31 +0000318
Chet Rameyac50fba2014-02-26 09:36:43 -0500319 running_trap = sig + 1;
Jari Aalto726f6381996-08-26 18:22:31 +0000320
321 if (sig == SIGINT)
322 {
Chet Rameyac50fba2014-02-26 09:36:43 -0500323 pending_traps[sig] = 0; /* XXX */
Jari Aalto726f6381996-08-26 18:22:31 +0000324 run_interrupt_trap ();
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000325 CLRINTERRUPT;
Jari Aalto726f6381996-08-26 18:22:31 +0000326 }
Jari Aalto31859422009-01-12 13:36:28 +0000327#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 {
Chet Rameyac50fba2014-02-26 09:36:43 -0500332 sigmodes[SIGCHLD] |= SIG_INPROGRESS;
Jari Aalto31859422009-01-12 13:36:28 +0000333 run_sigchld_trap (pending_traps[sig]); /* use as counter */
Chet Rameyac50fba2014-02-26 09:36:43 -0500334 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;
Jari Aalto31859422009-01-12 13:36:28 +0000352 }
353#endif
Jari Aaltobb706242000-03-17 21:46:59 +0000354 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. */
Jari Aaltob80f6442004-07-27 13:29:18 +0000371 internal_warning (_("run_pending_traps: bad value in trap_list[%d]: %p"),
Jari Aaltof73dda02001-11-13 17:56:06 +0000372 sig, trap_list[sig]);
Jari Aaltobb706242000-03-17 21:46:59 +0000373 if (trap_list[sig] == (char *)DEFAULT_SIG)
374 {
Jari Aaltob80f6442004-07-27 13:29:18 +0000375 internal_warning (_("run_pending_traps: signal handler is SIG_DFL, resending %d (%s) to myself"), sig, signal_name (sig));
Jari Aaltobb706242000-03-17 21:46:59 +0000376 kill (getpid (), sig);
377 }
378 }
Jari Aalto726f6381996-08-26 18:22:31 +0000379 else
Jari Aaltobb706242000-03-17 21:46:59 +0000380 {
Chet Rameyac50fba2014-02-26 09:36:43 -0500381 /* XXX - should we use save_parser_state/restore_parser_state? */
382 save_parser_state (&pstate);
Chet Ramey00018032011-11-21 20:51:19 -0500383 save_subst_varlist = subst_assign_varlist;
384 subst_assign_varlist = 0;
385
Chet Rameyac50fba2014-02-26 09:36:43 -0500386#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
Chet Ramey00018032011-11-21 20:51:19 -0500395
396 subst_assign_varlist = save_subst_varlist;
Chet Rameyac50fba2014-02-26 09:36:43 -0500397 restore_parser_state (&pstate);
Jari Aaltobb706242000-03-17 21:46:59 +0000398 }
Jari Aalto726f6381996-08-26 18:22:31 +0000399
Chet Rameyac50fba2014-02-26 09:36:43 -0500400 pending_traps[sig] = 0; /* XXX - move before evalstring? */
401 running_trap = 0;
Jari Aalto726f6381996-08-26 18:22:31 +0000402 }
403 }
404
Chet Ramey495aee42011-11-22 19:11:26 -0500405#if defined (ARRAY_VARS)
406 restore_pipestatus_array (ps);
407#endif
Jari Aalto726f6381996-08-26 18:22:31 +0000408 last_command_exit_value = old_exit_value;
409}
410
411sighandler
412trap_handler (sig)
413 int sig;
414{
Jari Aaltobb706242000-03-17 21:46:59 +0000415 int oerrno;
416
Jari Aalto31859422009-01-12 13:36:28 +0000417 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
Jari Aalto726f6381996-08-26 18:22:31 +0000425 if ((sig >= NSIG) ||
426 (trap_list[sig] == (char *)DEFAULT_SIG) ||
427 (trap_list[sig] == (char *)IGNORE_SIG))
Jari Aaltob80f6442004-07-27 13:29:18 +0000428 programming_error (_("trap_handler: bad signal %d"), sig);
Jari Aalto726f6381996-08-26 18:22:31 +0000429 else
430 {
Jari Aalto28ef6c32001-04-06 19:14:31 +0000431 oerrno = errno;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000432#if defined (MUST_REINSTALL_SIGHANDLERS)
Jari Aalto31859422009-01-12 13:36:28 +0000433# if defined (JOB_CONTROL) && defined (SIGCHLD)
434 if (sig != SIGCHLD)
435# endif /* JOB_CONTROL && SIGCHLD */
Jari Aalto726f6381996-08-26 18:22:31 +0000436 set_signal_handler (sig, trap_handler);
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000437#endif /* MUST_REINSTALL_SIGHANDLERS */
Jari Aalto726f6381996-08-26 18:22:31 +0000438
439 catch_flag = 1;
440 pending_traps[sig]++;
441
Chet Rameyac50fba2014-02-26 09:36:43 -0500442 trapped_signal_received = sig;
443
444 if (this_shell_builtin && (this_shell_builtin == wait_builtin))
Jari Aalto7117c2d2002-07-17 14:10:11 +0000445 {
446 wait_signal_received = sig;
Chet Rameyac50fba2014-02-26 09:36:43 -0500447 if (interrupt_immediately)
448 longjmp (wait_intr_buf, 1);
Jari Aalto7117c2d2002-07-17 14:10:11 +0000449 }
450
Chet Rameyac50fba2014-02-26 09:36:43 -0500451#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
Jari Aalto726f6381996-08-26 18:22:31 +0000459 if (interrupt_immediately)
460 run_pending_traps ();
Jari Aaltobb706242000-03-17 21:46:59 +0000461
462 errno = oerrno;
Jari Aalto726f6381996-08-26 18:22:31 +0000463 }
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000464
465 SIGRETURN (0);
Jari Aalto726f6381996-08-26 18:22:31 +0000466}
467
Chet Rameyac50fba2014-02-26 09:36:43 -0500468int
469first_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
479int
480any_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
490void
491check_signals ()
492{
493 CHECK_ALRM; /* set by the read builtin */
494 QUIT;
495}
496
497/* Convenience functions the rest of the shell can use */
498void
499check_signals_and_traps ()
500{
501 check_signals ();
502
503 run_pending_traps ();
504}
505
Jari Aalto726f6381996-08-26 18:22:31 +0000506#if defined (JOB_CONTROL) && defined (SIGCHLD)
Jari Aaltocce855b1998-04-17 19:52:44 +0000507
508#ifdef INCLUDE_UNUSED
Jari Aalto726f6381996-08-26 18:22:31 +0000509/* Make COMMAND_STRING be executed when SIGCHLD is caught. */
510void
511set_sigchld_trap (command_string)
512 char *command_string;
513{
Jari Aalto726f6381996-08-26 18:22:31 +0000514 set_signal (SIGCHLD, command_string);
515}
Jari Aaltocce855b1998-04-17 19:52:44 +0000516#endif
Jari Aalto726f6381996-08-26 18:22:31 +0000517
Jari Aalto95732b42005-12-07 14:08:12 +0000518/* Make COMMAND_STRING be executed when SIGCHLD is caught iff SIGCHLD
Jari Aalto31859422009-01-12 13:36:28 +0000519 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. */
Jari Aalto726f6381996-08-26 18:22:31 +0000523void
524maybe_set_sigchld_trap (command_string)
525 char *command_string;
526{
Jari Aalto31859422009-01-12 13:36:28 +0000527 if ((sigmodes[SIGCHLD] & SIG_TRAPPED) == 0 && trap_list[SIGCHLD] == (char *)IMPOSSIBLE_TRAP_HANDLER)
Jari Aalto726f6381996-08-26 18:22:31 +0000528 set_signal (SIGCHLD, command_string);
529}
Jari Aalto31859422009-01-12 13:36:28 +0000530
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. */
534void
535set_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}
Chet Rameyac50fba2014-02-26 09:36:43 -0500541
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. */
545void
546queue_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}
Jari Aalto726f6381996-08-26 18:22:31 +0000556#endif /* JOB_CONTROL && SIGCHLD */
557
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000558void
559set_debug_trap (command)
560 char *command;
561{
562 set_signal (DEBUG_TRAP, command);
563}
564
Jari Aaltof73dda02001-11-13 17:56:06 +0000565void
566set_error_trap (command)
567 char *command;
568{
569 set_signal (ERROR_TRAP, command);
570}
571
Jari Aaltob80f6442004-07-27 13:29:18 +0000572void
573set_return_trap (command)
574 char *command;
575{
576 set_signal (RETURN_TRAP, command);
577}
578
Jari Aaltocce855b1998-04-17 19:52:44 +0000579#ifdef INCLUDE_UNUSED
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000580void
Jari Aalto726f6381996-08-26 18:22:31 +0000581set_sigint_trap (command)
582 char *command;
583{
Jari Aalto726f6381996-08-26 18:22:31 +0000584 set_signal (SIGINT, command);
585}
Jari Aaltocce855b1998-04-17 19:52:44 +0000586#endif
Jari Aalto726f6381996-08-26 18:22:31 +0000587
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. */
591SigHandler *
592set_sigint_handler ()
593{
594 if (sigmodes[SIGINT] & SIG_HARD_IGNORE)
595 return ((SigHandler *)SIG_IGN);
596
597 else if (sigmodes[SIGINT] & SIG_IGNORED)
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000598 return ((SigHandler *)set_signal_handler (SIGINT, SIG_IGN)); /* XXX */
599
Jari Aalto726f6381996-08-26 18:22:31 +0000600 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
Jari Aalto06285672006-10-10 14:15:34 +0000608 return (set_signal_handler (SIGINT, termsig_sighandler));
Jari Aalto726f6381996-08-26 18:22:31 +0000609}
610
Jari Aaltoe8ce7751997-09-22 20:22:27 +0000611/* Return the correct handler for signal SIG according to the values in
612 sigmodes[SIG]. */
613SigHandler *
614trap_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
Jari Aalto726f6381996-08-26 18:22:31 +0000625/* Set SIG to call STRING as a command. */
626void
627set_signal (sig, string)
628 int sig;
629 char *string;
630{
Chet Rameyac50fba2014-02-26 09:36:43 -0500631 sigset_t set, oset;
632
Jari Aaltof73dda02001-11-13 17:56:06 +0000633 if (SPECIAL_TRAP (sig))
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000634 {
635 change_signal (sig, savestring (string));
Jari Aaltod166f041997-06-05 14:59:13 +0000636 if (sig == EXIT_TRAP && interactive == 0)
637 initialize_terminating_signals ();
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000638 return;
639 }
640
Jari Aalto726f6381996-08-26 18:22:31 +0000641 /* 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)
Jari Aalto06285672006-10-10 14:15:34 +0000652 GETORIGSIG (sig);
Jari Aalto726f6381996-08-26 18:22:31 +0000653 if (original_signals[sig] == SIG_IGN)
Jari Aalto06285672006-10-10 14:15:34 +0000654 return;
Jari Aalto726f6381996-08-26 18:22:31 +0000655 }
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 {
Chet Rameyac50fba2014-02-26 09:36:43 -0500663 BLOCK_SIGNAL (sig, set, oset);
Jari Aalto726f6381996-08-26 18:22:31 +0000664 change_signal (sig, savestring (string));
665 set_signal_handler (sig, trap_handler);
Chet Rameyac50fba2014-02-26 09:36:43 -0500666 UNBLOCK_SIGNAL (oset);
Jari Aalto726f6381996-08-26 18:22:31 +0000667 }
668 else
669 change_signal (sig, savestring (string));
670}
671
672static void
673free_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}
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000682
Jari Aalto726f6381996-08-26 18:22:31 +0000683/* If SIG has a string assigned to it, get rid of it. Then give it
684 VALUE. */
685static void
686change_signal (sig, value)
687 int sig;
688 char *value;
689{
Jari Aaltod166f041997-06-05 14:59:13 +0000690 if ((sigmodes[sig] & SIG_INPROGRESS) == 0)
691 free_trap_command (sig);
Jari Aalto726f6381996-08-26 18:22:31 +0000692 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
Chet Rameyac50fba2014-02-26 09:36:43 -0500703void
Jari Aalto726f6381996-08-26 18:22:31 +0000704get_original_signal (sig)
705 int sig;
706{
707 /* If we aren't sure the of the original value, then get it. */
Chet Ramey00018032011-11-21 20:51:19 -0500708 if (sig > 0 && sig < NSIG && original_signals[sig] == (SigHandler *)IMPOSSIBLE_TRAP_HANDLER)
Jari Aalto06285672006-10-10 14:15:34 +0000709 GETORIGSIG (sig);
Jari Aalto726f6381996-08-26 18:22:31 +0000710}
711
Chet Ramey495aee42011-11-22 19:11:26 -0500712void
713get_all_original_signals ()
714{
715 register int i;
716
717 for (i = 1; i < NSIG; i++)
718 GET_ORIGINAL_SIGNAL (i);
719}
720
721void
722set_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
Jari Aalto726f6381996-08-26 18:22:31 +0000730/* 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. */
734void
735restore_default_signal (sig)
736 int sig;
737{
Jari Aaltof73dda02001-11-13 17:56:06 +0000738 if (SPECIAL_TRAP (sig))
Jari Aalto726f6381996-08-26 18:22:31 +0000739 {
Jari Aaltob80f6442004-07-27 13:29:18 +0000740 if ((sig != DEBUG_TRAP && sig != ERROR_TRAP && sig != RETURN_TRAP) ||
741 (sigmodes[sig] & SIG_INPROGRESS) == 0)
Jari Aaltod166f041997-06-05 14:59:13 +0000742 free_trap_command (sig);
Jari Aalto726f6381996-08-26 18:22:31 +0000743 trap_list[sig] = (char *)NULL;
744 sigmodes[sig] &= ~SIG_TRAPPED;
Jari Aaltod166f041997-06-05 14:59:13 +0000745 if (sigmodes[sig] & SIG_INPROGRESS)
746 sigmodes[sig] |= SIG_CHANGED;
Jari Aalto726f6381996-08-26 18:22:31 +0000747 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. */
Chet Rameyac50fba2014-02-26 09:36:43 -0500758 /* 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))
Jari Aalto726f6381996-08-26 18:22:31 +0000763 return;
764
765 /* Only change the signal handler for SIG if it allows it. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000766 if ((sigmodes[sig] & SIG_NO_TRAP) == 0)
Jari Aalto726f6381996-08-26 18:22:31 +0000767 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. */
777void
778ignore_signal (sig)
779 int sig;
780{
Jari Aaltof73dda02001-11-13 17:56:06 +0000781 if (SPECIAL_TRAP (sig) && ((sigmodes[sig] & SIG_IGNORED) == 0))
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000782 {
783 change_signal (sig, (char *)IGNORE_SIG);
784 return;
785 }
786
Jari Aalto726f6381996-08-26 18:22:31 +0000787 GET_ORIGINAL_SIGNAL (sig);
788
789 /* A signal ignored on entry to the shell cannot be trapped or reset.
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000790 No error is reported when the user attempts to do so. */
Jari Aalto726f6381996-08-26 18:22:31 +0000791 if (sigmodes[sig] & SIG_HARD_IGNORE)
792 return;
793
794 /* If already trapped and ignored, no change necessary. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000795 if (sigmodes[sig] & SIG_IGNORED)
Jari Aalto726f6381996-08-26 18:22:31 +0000796 return;
797
798 /* Only change the signal handler for SIG if it allows it. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000799 if ((sigmodes[sig] & SIG_NO_TRAP) == 0)
Jari Aalto726f6381996-08-26 18:22:31 +0000800 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. */
809int
810run_exit_trap ()
811{
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000812 char *trap_command;
Jari Aaltob80f6442004-07-27 13:29:18 +0000813 int code, function_code, retval;
Chet Ramey495aee42011-11-22 19:11:26 -0500814#if defined (ARRAY_VARS)
815 ARRAY *ps;
816#endif
Jari Aalto726f6381996-08-26 18:22:31 +0000817
Jari Aaltob80f6442004-07-27 13:29:18 +0000818 trap_saved_exit_value = last_command_exit_value;
Chet Ramey495aee42011-11-22 19:11:26 -0500819#if defined (ARRAY_VARS)
820 ps = save_pipestatus_array ();
821#endif
Jari Aaltob80f6442004-07-27 13:29:18 +0000822 function_code = 0;
Jari Aalto726f6381996-08-26 18:22:31 +0000823
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000824 /* 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)
Jari Aalto726f6381996-08-26 18:22:31 +0000829 {
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000830 trap_command = savestring (trap_list[EXIT_TRAP]);
831 sigmodes[EXIT_TRAP] &= ~SIG_TRAPPED;
832 sigmodes[EXIT_TRAP] |= SIG_INPROGRESS;
Jari Aalto726f6381996-08-26 18:22:31 +0000833
Jari Aaltob80f6442004-07-27 13:29:18 +0000834 retval = trap_saved_exit_value;
835 running_trap = 1;
836
Chet Rameyac50fba2014-02-26 09:36:43 -0500837 code = setjmp_nosigs (top_level);
Jari Aalto726f6381996-08-26 18:22:31 +0000838
Jari Aaltob80f6442004-07-27 13:29:18 +0000839 /* If we're in a function, make sure return longjmps come here, too. */
840 if (return_catch_flag)
Chet Rameyac50fba2014-02-26 09:36:43 -0500841 function_code = setjmp_nosigs (return_catch);
Jari Aaltob80f6442004-07-27 13:29:18 +0000842
843 if (code == 0 && function_code == 0)
Jari Aaltocce855b1998-04-17 19:52:44 +0000844 {
845 reset_parser ();
Jari Aalto17345e52009-02-19 22:21:29 +0000846 parse_and_execute (trap_command, "exit trap", SEVAL_NONINT|SEVAL_NOHIST|SEVAL_RESETLINE);
Jari Aaltocce855b1998-04-17 19:52:44 +0000847 }
Jari Aaltob80f6442004-07-27 13:29:18 +0000848 else if (code == ERREXIT)
849 retval = last_command_exit_value;
Jari Aalto726f6381996-08-26 18:22:31 +0000850 else if (code == EXITPROG)
Jari Aaltob80f6442004-07-27 13:29:18 +0000851 retval = last_command_exit_value;
852 else if (function_code != 0)
853 retval = return_catch_value;
Jari Aalto726f6381996-08-26 18:22:31 +0000854 else
Jari Aaltob80f6442004-07-27 13:29:18 +0000855 retval = trap_saved_exit_value;
856
857 running_trap = 0;
858 return retval;
Jari Aalto726f6381996-08-26 18:22:31 +0000859 }
860
Chet Ramey495aee42011-11-22 19:11:26 -0500861#if defined (ARRAY_VARS)
862 restore_pipestatus_array (ps);
863#endif
Jari Aaltob80f6442004-07-27 13:29:18 +0000864 return (trap_saved_exit_value);
Jari Aalto726f6381996-08-26 18:22:31 +0000865}
866
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000867void
868run_trap_cleanup (sig)
Jari Aalto726f6381996-08-26 18:22:31 +0000869 int sig;
870{
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000871 sigmodes[sig] &= ~(SIG_INPROGRESS|SIG_CHANGED);
872}
873
Chet Rameyac50fba2014-02-26 09:36:43 -0500874#define RECURSIVE_SIG(s) (SPECIAL_TRAP(s) == 0)
875
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000876/* Run a trap command for SIG. SIG is one of the signals the shell treats
Jari Aaltob80f6442004-07-27 13:29:18 +0000877 specially. Returns the exit status of the executed trap command list. */
878static int
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000879_run_trap_internal (sig, tag)
880 int sig;
881 char *tag;
882{
883 char *trap_command, *old_trap;
Jari Aaltob80f6442004-07-27 13:29:18 +0000884 int trap_exit_value, *token_state;
Chet Rameyac50fba2014-02-26 09:36:43 -0500885 volatile int save_return_catch_flag, function_code;
886 int flags;
Jari Aaltob80f6442004-07-27 13:29:18 +0000887 procenv_t save_return_catch;
Chet Ramey00018032011-11-21 20:51:19 -0500888 WORD_LIST *save_subst_varlist;
Chet Rameyac50fba2014-02-26 09:36:43 -0500889 sh_parser_state_t pstate;
Chet Ramey495aee42011-11-22 19:11:26 -0500890#if defined (ARRAY_VARS)
891 ARRAY *ps;
892#endif
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000893
Jari Aaltob80f6442004-07-27 13:29:18 +0000894 trap_exit_value = function_code = 0;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000895 /* 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) &&
Chet Rameyac50fba2014-02-26 09:36:43 -0500899#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
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000904 ((sigmodes[sig] & SIG_INPROGRESS) == 0))
Chet Rameyac50fba2014-02-26 09:36:43 -0500905#endif
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000906 {
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;
Chet Rameyac50fba2014-02-26 09:36:43 -0500913
Chet Ramey495aee42011-11-22 19:11:26 -0500914#if defined (ARRAY_VARS)
915 ps = save_pipestatus_array ();
916#endif
Jari Aaltobb706242000-03-17 21:46:59 +0000917
Chet Rameyac50fba2014-02-26 09:36:43 -0500918 save_parser_state (&pstate);
Chet Ramey00018032011-11-21 20:51:19 -0500919 save_subst_varlist = subst_assign_varlist;
920 subst_assign_varlist = 0;
Jari Aaltob80f6442004-07-27 13:29:18 +0000921
Chet Rameyac50fba2014-02-26 09:36:43 -0500922#if defined (JOB_CONTROL)
Chet Ramey7f89f4c2014-03-28 11:53:02 -0400923 if (sig != DEBUG_TRAP) /* run_debug_trap does this */
924 save_pipeline (1); /* XXX only provides one save level */
Chet Rameyac50fba2014-02-26 09:36:43 -0500925#endif
926
Jari Aaltob80f6442004-07-27 13:29:18 +0000927 /* 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);
Chet Rameyac50fba2014-02-26 09:36:43 -0500932 function_code = setjmp_nosigs (return_catch);
Jari Aaltob80f6442004-07-27 13:29:18 +0000933 }
934
Jari Aalto17345e52009-02-19 22:21:29 +0000935 flags = SEVAL_NONINT|SEVAL_NOHIST;
Chet Ramey89a92862011-11-21 20:49:12 -0500936 if (sig != DEBUG_TRAP && sig != RETURN_TRAP && sig != ERROR_TRAP)
Jari Aalto17345e52009-02-19 22:21:29 +0000937 flags |= SEVAL_RESETLINE;
Jari Aaltob80f6442004-07-27 13:29:18 +0000938 if (function_code == 0)
Jari Aalto17345e52009-02-19 22:21:29 +0000939 parse_and_execute (trap_command, tag, flags);
Jari Aaltob80f6442004-07-27 13:29:18 +0000940
Chet Rameyac50fba2014-02-26 09:36:43 -0500941 trap_exit_value = last_command_exit_value;
942
943#if defined (JOB_CONTROL)
Chet Ramey7f89f4c2014-03-28 11:53:02 -0400944 if (sig != DEBUG_TRAP) /* run_debug_trap does this */
945 restore_pipeline (1);
Chet Rameyac50fba2014-02-26 09:36:43 -0500946#endif
Jari Aaltobb706242000-03-17 21:46:59 +0000947
Chet Ramey00018032011-11-21 20:51:19 -0500948 subst_assign_varlist = save_subst_varlist;
Chet Rameyac50fba2014-02-26 09:36:43 -0500949 restore_parser_state (&pstate);
Chet Ramey00018032011-11-21 20:51:19 -0500950
Chet Ramey495aee42011-11-22 19:11:26 -0500951#if defined (ARRAY_VARS)
952 restore_pipestatus_array (ps);
953#endif
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000954 running_trap = 0;
955
956 sigmodes[sig] &= ~SIG_INPROGRESS;
957
958 if (sigmodes[sig] & SIG_CHANGED)
959 {
Jari Aaltob80f6442004-07-27 13:29:18 +0000960#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);
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000967 sigmodes[sig] &= ~SIG_CHANGED;
968 }
Jari Aaltob80f6442004-07-27 13:29:18 +0000969
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 }
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000978 }
Jari Aaltob80f6442004-07-27 13:29:18 +0000979
980 return trap_exit_value;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000981}
982
Jari Aaltob80f6442004-07-27 13:29:18 +0000983int
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000984run_debug_trap ()
985{
Jari Aaltob80f6442004-07-27 13:29:18 +0000986 int trap_exit_value;
Chet Ramey89a92862011-11-21 20:49:12 -0500987 pid_t save_pgrp;
988 int save_pipe[2];
Jari Aaltob80f6442004-07-27 13:29:18 +0000989
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 {
Chet Ramey89a92862011-11-21 20:49:12 -0500994#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
Jari Aaltob80f6442004-07-27 13:29:18 +00001004 trap_exit_value = _run_trap_internal (DEBUG_TRAP, "debug trap");
Chet Ramey89a92862011-11-21 20:49:12 -05001005
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
Jari Aaltob80f6442004-07-27 13:29:18 +00001017
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;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001029}
1030
Jari Aaltof73dda02001-11-13 17:56:06 +00001031void
1032run_error_trap ()
1033{
Jari Aaltob80f6442004-07-27 13:29:18 +00001034 if ((sigmodes[ERROR_TRAP] & SIG_TRAPPED) && ((sigmodes[ERROR_TRAP] & SIG_IGNORED) == 0) && (sigmodes[ERROR_TRAP] & SIG_INPROGRESS) == 0)
Jari Aaltof73dda02001-11-13 17:56:06 +00001035 _run_trap_internal (ERROR_TRAP, "error trap");
1036}
1037
Jari Aaltob80f6442004-07-27 13:29:18 +00001038void
1039run_return_trap ()
1040{
1041 int old_exit_value;
1042
Jari Aalto95732b42005-12-07 14:08:12 +00001043#if 0
1044 if ((sigmodes[DEBUG_TRAP] & SIG_TRAPPED) && (sigmodes[DEBUG_TRAP] & SIG_INPROGRESS))
1045 return;
1046#endif
1047
Jari Aaltob80f6442004-07-27 13:29:18 +00001048 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
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001056/* Run a trap set on SIGINT. This is called from throw_to_top_level (), and
1057 declared here to localize the trap functions. */
1058void
1059run_interrupt_trap ()
1060{
1061 _run_trap_internal (SIGINT, "interrupt trap");
Jari Aalto726f6381996-08-26 18:22:31 +00001062}
1063
1064/* Free all the allocated strings in the list of traps and reset the trap
Chet Ramey00018032011-11-21 20:51:19 -05001065 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
Chet Rameyac50fba2014-02-26 09:36:43 -05001067 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. */
Jari Aalto726f6381996-08-26 18:22:31 +00001071void
1072free_trap_strings ()
1073{
1074 register int i;
1075
Jari Aaltof73dda02001-11-13 17:56:06 +00001076 for (i = 0; i < BASH_NSIG; i++)
Chet Rameyac50fba2014-02-26 09:36:43 -05001077 {
1078 if (trap_list[i] != (char *)IGNORE_SIG)
1079 free_trap_string (i);
1080 }
Jari Aaltob80f6442004-07-27 13:29:18 +00001081 trap_list[DEBUG_TRAP] = trap_list[EXIT_TRAP] = trap_list[ERROR_TRAP] = trap_list[RETURN_TRAP] = (char *)NULL;
Jari Aalto726f6381996-08-26 18:22:31 +00001082}
Chet Ramey00018032011-11-21 20:51:19 -05001083
1084/* Free a trap command string associated with SIG without changing signal
1085 disposition. Intended to be called from free_trap_strings() */
1086static void
1087free_trap_string (sig)
1088 int sig;
1089{
1090 change_signal (sig, (char *)DEFAULT_SIG);
1091 sigmodes[sig] &= ~SIG_TRAPPED;
1092}
Jari Aalto726f6381996-08-26 18:22:31 +00001093
Chet Ramey495aee42011-11-22 19:11:26 -05001094/* Reset the handler for SIG to the original value but leave the trap string
1095 in place. */
Jari Aalto726f6381996-08-26 18:22:31 +00001096static void
1097reset_signal (sig)
1098 int sig;
1099{
1100 set_signal_handler (sig, original_signals[sig]);
Jari Aalto7117c2d2002-07-17 14:10:11 +00001101 sigmodes[sig] &= ~SIG_TRAPPED;
Jari Aalto726f6381996-08-26 18:22:31 +00001102}
1103
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001104/* Set the handler signal SIG to the original and free any trap
1105 command associated with it. */
1106static void
1107restore_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
1115static void
1116reset_or_restore_signal_handlers (reset)
Jari Aaltof73dda02001-11-13 17:56:06 +00001117 sh_resetsig_func_t *reset;
Jari Aalto726f6381996-08-26 18:22:31 +00001118{
1119 register int i;
1120
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001121 /* Take care of the exit trap first */
1122 if (sigmodes[EXIT_TRAP] & SIG_TRAPPED)
Jari Aalto726f6381996-08-26 18:22:31 +00001123 {
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001124 sigmodes[EXIT_TRAP] &= ~SIG_TRAPPED;
Jari Aalto95732b42005-12-07 14:08:12 +00001125 if (reset != reset_signal)
1126 {
1127 free_trap_command (EXIT_TRAP);
1128 trap_list[EXIT_TRAP] = (char *)NULL;
1129 }
Jari Aalto726f6381996-08-26 18:22:31 +00001130 }
Jari Aaltob80f6442004-07-27 13:29:18 +00001131
Jari Aalto726f6381996-08-26 18:22:31 +00001132 for (i = 1; i < NSIG; i++)
1133 {
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001134 if (sigmodes[i] & SIG_TRAPPED)
Jari Aalto726f6381996-08-26 18:22:31 +00001135 {
1136 if (trap_list[i] == (char *)IGNORE_SIG)
1137 set_signal_handler (i, SIG_IGN);
1138 else
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001139 (*reset) (i);
Jari Aalto726f6381996-08-26 18:22:31 +00001140 }
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001141 else if (sigmodes[i] & SIG_SPECIAL)
1142 (*reset) (i);
Jari Aalto726f6381996-08-26 18:22:31 +00001143 }
Jari Aaltof73dda02001-11-13 17:56:06 +00001144
1145 /* Command substitution and other child processes don't inherit the
Jari Aaltob80f6442004-07-27 13:29:18 +00001146 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. */
Jari Aalto06285672006-10-10 14:15:34 +00001150 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)
Jari Aaltob80f6442004-07-27 13:29:18 +00001156 sigmodes[ERROR_TRAP] &= ~SIG_TRAPPED;
Jari Aalto726f6381996-08-26 18:22:31 +00001157}
1158
Jari Aaltof73dda02001-11-13 17:56:06 +00001159/* Reset trapped signals to their original values, but don't free the
Chet Ramey495aee42011-11-22 19:11:26 -05001160 trap strings. Called by the command substitution code and other places
1161 that create a "subshell environment". */
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001162void
1163reset_signal_handlers ()
1164{
1165 reset_or_restore_signal_handlers (reset_signal);
1166}
1167
Jari Aalto726f6381996-08-26 18:22:31 +00001168/* 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. */
1171void
1172restore_original_signals ()
1173{
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001174 reset_or_restore_signal_handlers (restore_signal);
Jari Aalto726f6381996-08-26 18:22:31 +00001175}
1176
1177/* If a trap handler exists for signal SIG, then call it; otherwise just
Chet Rameyac50fba2014-02-26 09:36:43 -05001178 return failure. Returns 1 if it called the trap handler. */
Jari Aalto726f6381996-08-26 18:22:31 +00001179int
1180maybe_call_trap_handler (sig)
1181 int sig;
1182{
1183 /* Call the trap handler for SIG if the signal is trapped and not ignored. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001184 if ((sigmodes[sig] & SIG_TRAPPED) && ((sigmodes[sig] & SIG_IGNORED) == 0))
Jari Aalto726f6381996-08-26 18:22:31 +00001185 {
1186 switch (sig)
1187 {
1188 case SIGINT:
1189 run_interrupt_trap ();
1190 break;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001191 case EXIT_TRAP:
Jari Aalto726f6381996-08-26 18:22:31 +00001192 run_exit_trap ();
1193 break;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001194 case DEBUG_TRAP:
1195 run_debug_trap ();
1196 break;
Jari Aaltof73dda02001-11-13 17:56:06 +00001197 case ERROR_TRAP:
1198 run_error_trap ();
1199 break;
Jari Aalto726f6381996-08-26 18:22:31 +00001200 default:
1201 trap_handler (sig);
1202 break;
1203 }
1204 return (1);
1205 }
1206 else
1207 return (0);
1208}
1209
1210int
1211signal_is_trapped (sig)
1212 int sig;
1213{
1214 return (sigmodes[sig] & SIG_TRAPPED);
1215}
1216
1217int
Chet Rameyac50fba2014-02-26 09:36:43 -05001218signal_is_pending (sig)
1219 int sig;
1220{
1221 return (pending_traps[sig]);
1222}
1223
1224int
Jari Aalto726f6381996-08-26 18:22:31 +00001225signal_is_special (sig)
1226 int sig;
1227{
1228 return (sigmodes[sig] & SIG_SPECIAL);
1229}
1230
1231int
1232signal_is_ignored (sig)
1233 int sig;
1234{
1235 return (sigmodes[sig] & SIG_IGNORED);
1236}
1237
Chet Ramey495aee42011-11-22 19:11:26 -05001238int
1239signal_is_hard_ignored (sig)
1240 int sig;
1241{
1242 return (sigmodes[sig] & SIG_HARD_IGNORE);
1243}
1244
Jari Aalto726f6381996-08-26 18:22:31 +00001245void
Chet Rameyac50fba2014-02-26 09:36:43 -05001246set_signal_hard_ignored (sig)
Jari Aalto726f6381996-08-26 18:22:31 +00001247 int sig;
1248{
1249 sigmodes[sig] |= SIG_HARD_IGNORE;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001250 original_signals[sig] = SIG_IGN;
Jari Aalto726f6381996-08-26 18:22:31 +00001251}
Jari Aalto95732b42005-12-07 14:08:12 +00001252
Chet Rameyac50fba2014-02-26 09:36:43 -05001253void
1254set_signal_ignored (sig)
1255 int sig;
1256{
1257 original_signals[sig] = SIG_IGN;
1258}
1259
Jari Aalto95732b42005-12-07 14:08:12 +00001260int
1261signal_in_progress (sig)
1262 int sig;
1263{
1264 return (sigmodes[sig] & SIG_INPROGRESS);
1265}