1 /* trap.c -- Not the trap command, but useful functions for manipulating
2 those objects. The trap command is in builtins/trap.def. */
4 /* Copyright (C) 1987-2002 Free Software Foundation, Inc.
6 This file is part of GNU Bash, the Bourne Again SHell.
8 Bash is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 2, or (at your option) any later
13 Bash is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 You should have received a copy of the GNU General Public License along
19 with Bash; see the file COPYING. If not, write to the Free Software
20 Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
24 #if defined (HAVE_UNISTD_H)
28 #include "bashtypes.h"
37 #include "input.h" /* for save_token_state, restore_token_state */
40 #include "builtins/common.h"
41 #include "builtins/builtext.h"
47 /* Flags which describe the current handling state of a signal. */
48 #define SIG_INHERITED 0x0 /* Value inherited from parent. */
49 #define SIG_TRAPPED 0x1 /* Currently trapped. */
50 #define SIG_HARD_IGNORE 0x2 /* Signal was ignored on shell entry. */
51 #define SIG_SPECIAL 0x4 /* Treat this signal specially. */
52 #define SIG_NO_TRAP 0x8 /* Signal cannot be trapped. */
53 #define SIG_INPROGRESS 0x10 /* Signal handler currently executing. */
54 #define SIG_CHANGED 0x20 /* Trap value changed in trap handler. */
55 #define SIG_IGNORED 0x40 /* The signal is currently being ignored. */
57 #define SPECIAL_TRAP(s) ((s) == EXIT_TRAP || (s) == DEBUG_TRAP || (s) == ERROR_TRAP)
59 /* An array of such flags, one for each signal, describing what the
60 shell will do with a signal. DEBUG_TRAP == NSIG; some code below
62 static int sigmodes[BASH_NSIG];
64 static void free_trap_command __P((int));
65 static void change_signal __P((int, char *));
67 static void get_original_signal __P((int));
69 static void _run_trap_internal __P((int, char *));
71 static void reset_signal __P((int));
72 static void restore_signal __P((int));
73 static void reset_or_restore_signal_handlers __P((sh_resetsig_func_t *));
75 /* Variables used here but defined in other files. */
76 extern int interrupt_immediately;
77 extern int last_command_exit_value;
78 extern int line_number;
80 extern sh_builtin_func_t *this_shell_builtin;
81 extern procenv_t wait_intr_buf;
83 /* The list of things to do originally, before we started trapping. */
84 SigHandler *original_signals[NSIG];
86 /* For each signal, a slot for a string, which is a command to be
87 executed when that signal is recieved. The slot can also contain
88 DEFAULT_SIG, which means do whatever you were going to do before
89 you were so rudely interrupted, or IGNORE_SIG, which says ignore
91 char *trap_list[BASH_NSIG];
93 /* A bitmap of signals received for which we have trap handlers. */
94 int pending_traps[NSIG];
96 /* Set to the number of the signal we're running the trap for + 1.
97 Used in execute_cmd.c and builtins/common.c to clean up when
98 parse_and_execute does not return normally after executing the
99 trap command (e.g., when `return' is executed in the trap command). */
102 /* The value of line_number when the trap started executing, since
103 parse_and_execute resets it to 1 and the trap command might want
105 int trap_line_number;
107 /* The (trapped) signal received while executing in the `wait' builtin */
108 int wait_signal_received;
110 /* A value which can never be the target of a trap handler. */
111 #define IMPOSSIBLE_TRAP_HANDLER (SigHandler *)initialize_traps
118 trap_list[EXIT_TRAP] = trap_list[DEBUG_TRAP] = trap_list[ERROR_TRAP] = (char *)NULL;
119 sigmodes[EXIT_TRAP] = sigmodes[DEBUG_TRAP] = sigmodes[ERROR_TRAP] = SIG_INHERITED;
120 original_signals[EXIT_TRAP] = IMPOSSIBLE_TRAP_HANDLER;
122 for (i = 1; i < NSIG; i++)
124 pending_traps[i] = 0;
125 trap_list[i] = (char *)DEFAULT_SIG;
126 sigmodes[i] = SIG_INHERITED;
127 original_signals[i] = IMPOSSIBLE_TRAP_HANDLER;
130 /* Show which signals are treated specially by the shell. */
131 #if defined (SIGCHLD)
132 original_signals[SIGCHLD] =
133 (SigHandler *) set_signal_handler (SIGCHLD, SIG_DFL);
134 set_signal_handler (SIGCHLD, original_signals[SIGCHLD]);
135 sigmodes[SIGCHLD] |= (SIG_SPECIAL | SIG_NO_TRAP);
138 original_signals[SIGINT] =
139 (SigHandler *) set_signal_handler (SIGINT, SIG_DFL);
140 set_signal_handler (SIGINT, original_signals[SIGINT]);
141 sigmodes[SIGINT] |= SIG_SPECIAL;
143 #if defined (__BEOS__)
144 /* BeOS sets SIGINT to SIG_IGN! */
145 original_signals[SIGINT] = SIG_DFL;
148 original_signals[SIGQUIT] =
149 (SigHandler *) set_signal_handler (SIGQUIT, SIG_DFL);
150 set_signal_handler (SIGQUIT, original_signals[SIGQUIT]);
151 sigmodes[SIGQUIT] |= SIG_SPECIAL;
155 original_signals[SIGTERM] =
156 (SigHandler *)set_signal_handler (SIGTERM, SIG_DFL);
157 set_signal_handler (SIGTERM, original_signals[SIGTERM]);
158 sigmodes[SIGTERM] |= SIG_SPECIAL;
162 #ifdef INCLUDE_UNUSED
163 /* Return a printable representation of the trap handler for SIG. */
165 trap_handler_string (sig)
168 if (trap_list[sig] == (char *)DEFAULT_SIG)
169 return "DEFAULT_SIG";
170 else if (trap_list[sig] == (char *)IGNORE_SIG)
172 else if (trap_list[sig] == (char *)IMPOSSIBLE_TRAP_HANDLER)
173 return "IMPOSSIBLE_TRAP_HANDLER";
174 else if (trap_list[sig])
175 return trap_list[sig];
181 /* Return the print name of this signal. */
188 /* on cygwin32, signal_names[sig] could be null */
189 ret = (sig >= BASH_NSIG || sig < 0) ? "bad signal number" : signal_names[sig];
191 ret = "unrecognized signal number";
195 /* Turn a string into a signal number, or a number into
196 a signal number. If STRING is "2", "SIGINT", or "INT",
197 then (int)2 is returned. Return NO_SIG if STRING doesn't
198 contain a valid signal descriptor. */
200 decode_signal (string)
205 if (legal_number (string, &sig))
206 return ((sig >= 0 && sig < NSIG) ? (int)sig : NO_SIG);
208 /* A leading `SIG' may be omitted. */
209 for (sig = 0; sig < BASH_NSIG; sig++)
211 if (signal_names[sig] == 0 || signal_names[sig][0] == '\0')
213 if (strcasecmp (string, signal_names[sig]) == 0 ||
214 (STREQN (signal_names[sig], "SIG", 3) &&
215 strcasecmp (string, &(signal_names[sig])[3]) == 0))
222 /* Non-zero when we catch a trapped signal. */
223 static int catch_flag;
229 int old_exit_value, *token_state;
231 if (catch_flag == 0) /* simple optimization */
236 /* Preserve $? when running trap. */
237 old_exit_value = last_command_exit_value;
239 for (sig = 1; sig < NSIG; sig++)
241 /* XXX this could be made into a counter by using
242 while (pending_traps[sig]--) instead of the if statement. */
243 if (pending_traps[sig])
245 #if defined (HAVE_POSIX_SIGNALS)
251 sigaddset (&set, sig);
252 sigprocmask (SIG_BLOCK, &set, &oset);
254 # if defined (HAVE_BSD_SIGNALS)
255 int oldmask = sigblock (sigmask (sig));
257 #endif /* HAVE_POSIX_SIGNALS */
261 run_interrupt_trap ();
264 else if (trap_list[sig] == (char *)DEFAULT_SIG ||
265 trap_list[sig] == (char *)IGNORE_SIG ||
266 trap_list[sig] == (char *)IMPOSSIBLE_TRAP_HANDLER)
268 /* This is possible due to a race condition. Say a bash
269 process has SIGTERM trapped. A subshell is spawned
270 using { list; } & and the parent does something and kills
271 the subshell with SIGTERM. It's possible for the subshell
272 to set pending_traps[SIGTERM] to 1 before the code in
273 execute_cmd.c eventually calls restore_original_signals
274 to reset the SIGTERM signal handler in the subshell. The
275 next time run_pending_traps is called, pending_traps[SIGTERM]
276 will be 1, but the trap handler in trap_list[SIGTERM] will
277 be invalid (probably DEFAULT_SIG, but it could be IGNORE_SIG).
278 Unless we catch this, the subshell will dump core when
279 trap_list[SIGTERM] == DEFAULT_SIG, because DEFAULT_SIG is
281 internal_warning ("run_pending_traps: bad value in trap_list[%d]: %p",
282 sig, trap_list[sig]);
283 if (trap_list[sig] == (char *)DEFAULT_SIG)
285 internal_warning ("run_pending_traps: signal handler is SIG_DFL, resending %d (%s) to myself", sig, signal_name (sig));
286 kill (getpid (), sig);
291 token_state = save_token_state ();
292 parse_and_execute (savestring (trap_list[sig]), "trap", SEVAL_NONINT|SEVAL_NOHIST);
293 restore_token_state (token_state);
297 pending_traps[sig] = 0;
299 #if defined (HAVE_POSIX_SIGNALS)
300 sigprocmask (SIG_SETMASK, &oset, (sigset_t *)NULL);
302 # if defined (HAVE_BSD_SIGNALS)
303 sigsetmask (oldmask);
305 #endif /* POSIX_VERSION */
309 last_command_exit_value = old_exit_value;
319 (trap_list[sig] == (char *)DEFAULT_SIG) ||
320 (trap_list[sig] == (char *)IGNORE_SIG))
321 programming_error ("trap_handler: bad signal %d", sig);
325 #if defined (MUST_REINSTALL_SIGHANDLERS)
326 set_signal_handler (sig, trap_handler);
327 #endif /* MUST_REINSTALL_SIGHANDLERS */
330 pending_traps[sig]++;
332 if (interrupt_immediately && this_shell_builtin && (this_shell_builtin == wait_builtin))
334 wait_signal_received = sig;
335 longjmp (wait_intr_buf, 1);
338 if (interrupt_immediately)
339 run_pending_traps ();
347 #if defined (JOB_CONTROL) && defined (SIGCHLD)
349 #ifdef INCLUDE_UNUSED
350 /* Make COMMAND_STRING be executed when SIGCHLD is caught. */
352 set_sigchld_trap (command_string)
353 char *command_string;
355 set_signal (SIGCHLD, command_string);
359 /* Make COMMAND_STRING be executed when SIGCHLD is caught iff the current
360 SIGCHLD trap handler is DEFAULT_SIG. */
362 maybe_set_sigchld_trap (command_string)
363 char *command_string;
365 if ((sigmodes[SIGCHLD] & SIG_TRAPPED) == 0)
366 set_signal (SIGCHLD, command_string);
368 #endif /* JOB_CONTROL && SIGCHLD */
371 set_debug_trap (command)
374 set_signal (DEBUG_TRAP, command);
378 set_error_trap (command)
381 set_signal (ERROR_TRAP, command);
384 #ifdef INCLUDE_UNUSED
386 set_sigint_trap (command)
389 set_signal (SIGINT, command);
393 /* Reset the SIGINT handler so that subshells that are doing `shellsy'
394 things, like waiting for command substitution or executing commands
395 in explicit subshells ( ( cmd ) ), can catch interrupts properly. */
397 set_sigint_handler ()
399 if (sigmodes[SIGINT] & SIG_HARD_IGNORE)
400 return ((SigHandler *)SIG_IGN);
402 else if (sigmodes[SIGINT] & SIG_IGNORED)
403 return ((SigHandler *)set_signal_handler (SIGINT, SIG_IGN)); /* XXX */
405 else if (sigmodes[SIGINT] & SIG_TRAPPED)
406 return ((SigHandler *)set_signal_handler (SIGINT, trap_handler));
408 /* The signal is not trapped, so set the handler to the shell's special
409 interrupt handler. */
410 else if (interactive) /* XXX - was interactive_shell */
411 return (set_signal_handler (SIGINT, sigint_sighandler));
413 return (set_signal_handler (SIGINT, termination_unwind_protect));
416 /* Return the correct handler for signal SIG according to the values in
419 trap_to_sighandler (sig)
422 if (sigmodes[sig] & (SIG_IGNORED|SIG_HARD_IGNORE))
424 else if (sigmodes[sig] & SIG_TRAPPED)
425 return (trap_handler);
430 /* Set SIG to call STRING as a command. */
432 set_signal (sig, string)
436 if (SPECIAL_TRAP (sig))
438 change_signal (sig, savestring (string));
439 if (sig == EXIT_TRAP && interactive == 0)
440 initialize_terminating_signals ();
444 /* A signal ignored on entry to the shell cannot be trapped or reset, but
445 no error is reported when attempting to do so. -- Posix.2 */
446 if (sigmodes[sig] & SIG_HARD_IGNORE)
449 /* Make sure we have original_signals[sig] if the signal has not yet
451 if ((sigmodes[sig] & SIG_TRAPPED) == 0)
453 /* If we aren't sure of the original value, check it. */
454 if (original_signals[sig] == IMPOSSIBLE_TRAP_HANDLER)
456 original_signals[sig] = (SigHandler *)set_signal_handler (sig, SIG_DFL);
457 set_signal_handler (sig, original_signals[sig]);
460 /* Signals ignored on entry to the shell cannot be trapped or reset. */
461 if (original_signals[sig] == SIG_IGN)
463 sigmodes[sig] |= SIG_HARD_IGNORE;
468 /* Only change the system signal handler if SIG_NO_TRAP is not set.
469 The trap command string is changed in either case. The shell signal
470 handlers for SIGINT and SIGCHLD run the user specified traps in an
471 environment in which it is safe to do so. */
472 if ((sigmodes[sig] & SIG_NO_TRAP) == 0)
474 set_signal_handler (sig, SIG_IGN);
475 change_signal (sig, savestring (string));
476 set_signal_handler (sig, trap_handler);
479 change_signal (sig, savestring (string));
483 free_trap_command (sig)
486 if ((sigmodes[sig] & SIG_TRAPPED) && trap_list[sig] &&
487 (trap_list[sig] != (char *)IGNORE_SIG) &&
488 (trap_list[sig] != (char *)DEFAULT_SIG) &&
489 (trap_list[sig] != (char *)IMPOSSIBLE_TRAP_HANDLER))
490 free (trap_list[sig]);
493 /* If SIG has a string assigned to it, get rid of it. Then give it
496 change_signal (sig, value)
500 if ((sigmodes[sig] & SIG_INPROGRESS) == 0)
501 free_trap_command (sig);
502 trap_list[sig] = value;
504 sigmodes[sig] |= SIG_TRAPPED;
505 if (value == (char *)IGNORE_SIG)
506 sigmodes[sig] |= SIG_IGNORED;
508 sigmodes[sig] &= ~SIG_IGNORED;
509 if (sigmodes[sig] & SIG_INPROGRESS)
510 sigmodes[sig] |= SIG_CHANGED;
513 #define GET_ORIGINAL_SIGNAL(sig) \
514 if (sig && sig < NSIG && original_signals[sig] == IMPOSSIBLE_TRAP_HANDLER) \
515 get_original_signal (sig)
518 get_original_signal (sig)
521 /* If we aren't sure the of the original value, then get it. */
522 if (original_signals[sig] == (SigHandler *)IMPOSSIBLE_TRAP_HANDLER)
524 original_signals[sig] =
525 (SigHandler *) set_signal_handler (sig, SIG_DFL);
526 set_signal_handler (sig, original_signals[sig]);
528 /* Signals ignored on entry to the shell cannot be trapped. */
529 if (original_signals[sig] == SIG_IGN)
530 sigmodes[sig] |= SIG_HARD_IGNORE;
534 /* Restore the default action for SIG; i.e., the action the shell
535 would have taken before you used the trap command. This is called
536 from trap_builtin (), which takes care to restore the handlers for
537 the signals the shell treats specially. */
539 restore_default_signal (sig)
542 if (SPECIAL_TRAP (sig))
544 if ((sig != DEBUG_TRAP && sig != ERROR_TRAP) || (sigmodes[sig] & SIG_INPROGRESS) == 0)
545 free_trap_command (sig);
546 trap_list[sig] = (char *)NULL;
547 sigmodes[sig] &= ~SIG_TRAPPED;
548 if (sigmodes[sig] & SIG_INPROGRESS)
549 sigmodes[sig] |= SIG_CHANGED;
553 GET_ORIGINAL_SIGNAL (sig);
555 /* A signal ignored on entry to the shell cannot be trapped or reset, but
556 no error is reported when attempting to do so. Thanks Posix.2. */
557 if (sigmodes[sig] & SIG_HARD_IGNORE)
560 /* If we aren't trapping this signal, don't bother doing anything else. */
561 if ((sigmodes[sig] & SIG_TRAPPED) == 0)
564 /* Only change the signal handler for SIG if it allows it. */
565 if ((sigmodes[sig] & SIG_NO_TRAP) == 0)
566 set_signal_handler (sig, original_signals[sig]);
568 /* Change the trap command in either case. */
569 change_signal (sig, (char *)DEFAULT_SIG);
571 /* Mark the signal as no longer trapped. */
572 sigmodes[sig] &= ~SIG_TRAPPED;
575 /* Make this signal be ignored. */
580 if (SPECIAL_TRAP (sig) && ((sigmodes[sig] & SIG_IGNORED) == 0))
582 change_signal (sig, (char *)IGNORE_SIG);
586 GET_ORIGINAL_SIGNAL (sig);
588 /* A signal ignored on entry to the shell cannot be trapped or reset.
589 No error is reported when the user attempts to do so. */
590 if (sigmodes[sig] & SIG_HARD_IGNORE)
593 /* If already trapped and ignored, no change necessary. */
594 if (sigmodes[sig] & SIG_IGNORED)
597 /* Only change the signal handler for SIG if it allows it. */
598 if ((sigmodes[sig] & SIG_NO_TRAP) == 0)
599 set_signal_handler (sig, SIG_IGN);
601 /* Change the trap command in either case. */
602 change_signal (sig, (char *)IGNORE_SIG);
605 /* Handle the calling of "trap 0". The only sticky situation is when
606 the command to be executed includes an "exit". This is why we have
607 to provide our own place for top_level to jump to. */
612 int code, old_exit_value;
614 old_exit_value = last_command_exit_value;
616 /* Run the trap only if signal 0 is trapped and not ignored, and we are not
617 currently running in the trap handler (call to exit in the list of
618 commands given to trap 0). */
619 if ((sigmodes[EXIT_TRAP] & SIG_TRAPPED) &&
620 (sigmodes[EXIT_TRAP] & (SIG_IGNORED|SIG_INPROGRESS)) == 0)
622 trap_command = savestring (trap_list[EXIT_TRAP]);
623 sigmodes[EXIT_TRAP] &= ~SIG_TRAPPED;
624 sigmodes[EXIT_TRAP] |= SIG_INPROGRESS;
626 code = setjmp (top_level);
631 parse_and_execute (trap_command, "exit trap", SEVAL_NONINT|SEVAL_NOHIST);
633 else if (code == EXITPROG)
634 return (last_command_exit_value);
636 return (old_exit_value);
639 return (old_exit_value);
643 run_trap_cleanup (sig)
646 sigmodes[sig] &= ~(SIG_INPROGRESS|SIG_CHANGED);
649 /* Run a trap command for SIG. SIG is one of the signals the shell treats
652 _run_trap_internal (sig, tag)
656 char *trap_command, *old_trap;
657 int old_exit_value, *token_state;
659 /* Run the trap only if SIG is trapped and not ignored, and we are not
660 currently executing in the trap handler. */
661 if ((sigmodes[sig] & SIG_TRAPPED) && ((sigmodes[sig] & SIG_IGNORED) == 0) &&
662 (trap_list[sig] != (char *)IMPOSSIBLE_TRAP_HANDLER) &&
663 ((sigmodes[sig] & SIG_INPROGRESS) == 0))
665 old_trap = trap_list[sig];
666 sigmodes[sig] |= SIG_INPROGRESS;
667 sigmodes[sig] &= ~SIG_CHANGED; /* just to be sure */
668 trap_command = savestring (old_trap);
670 running_trap = sig + 1;
671 old_exit_value = last_command_exit_value;
672 /* Need to copy the value of line_number because parse_and_execute
673 resets it to 1, and the trap command might want it. */
674 trap_line_number = line_number;
676 token_state = save_token_state ();
677 parse_and_execute (trap_command, tag, SEVAL_NONINT|SEVAL_NOHIST);
678 restore_token_state (token_state);
681 last_command_exit_value = old_exit_value;
684 sigmodes[sig] &= ~SIG_INPROGRESS;
686 if (sigmodes[sig] & SIG_CHANGED)
689 sigmodes[sig] &= ~SIG_CHANGED;
697 if ((sigmodes[DEBUG_TRAP] & SIG_TRAPPED) && ((sigmodes[DEBUG_TRAP] & SIG_INPROGRESS) == 0))
698 _run_trap_internal (DEBUG_TRAP, "debug trap");
704 if ((sigmodes[ERROR_TRAP] & SIG_TRAPPED) && (sigmodes[ERROR_TRAP] & SIG_INPROGRESS) == 0)
705 _run_trap_internal (ERROR_TRAP, "error trap");
708 /* Run a trap set on SIGINT. This is called from throw_to_top_level (), and
709 declared here to localize the trap functions. */
711 run_interrupt_trap ()
713 _run_trap_internal (SIGINT, "interrupt trap");
716 #ifdef INCLUDE_UNUSED
717 /* Free all the allocated strings in the list of traps and reset the trap
718 values to the default. */
724 for (i = 0; i < BASH_NSIG; i++)
726 free_trap_command (i);
727 trap_list[i] = (char *)DEFAULT_SIG;
728 sigmodes[i] &= ~SIG_TRAPPED;
730 trap_list[DEBUG_TRAP] = trap_list[EXIT_TRAP] = trap_list[ERROR_TRAP] = (char *)NULL;
734 /* Reset the handler for SIG to the original value. */
739 set_signal_handler (sig, original_signals[sig]);
740 sigmodes[sig] &= ~SIG_TRAPPED;
743 /* Set the handler signal SIG to the original and free any trap
744 command associated with it. */
749 set_signal_handler (sig, original_signals[sig]);
750 change_signal (sig, (char *)DEFAULT_SIG);
751 sigmodes[sig] &= ~SIG_TRAPPED;
755 reset_or_restore_signal_handlers (reset)
756 sh_resetsig_func_t *reset;
760 /* Take care of the exit trap first */
761 if (sigmodes[EXIT_TRAP] & SIG_TRAPPED)
763 free_trap_command (EXIT_TRAP);
764 trap_list[EXIT_TRAP] = (char *)NULL;
765 sigmodes[EXIT_TRAP] &= ~SIG_TRAPPED;
767 for (i = 1; i < NSIG; i++)
769 if (sigmodes[i] & SIG_TRAPPED)
771 if (trap_list[i] == (char *)IGNORE_SIG)
772 set_signal_handler (i, SIG_IGN);
776 else if (sigmodes[i] & SIG_SPECIAL)
780 /* Command substitution and other child processes don't inherit the
781 debug or error traps. */
782 sigmodes[DEBUG_TRAP] &= ~SIG_TRAPPED;
783 sigmodes[ERROR_TRAP] &= ~SIG_TRAPPED;
786 /* Reset trapped signals to their original values, but don't free the
787 trap strings. Called by the command substitution code. */
789 reset_signal_handlers ()
791 reset_or_restore_signal_handlers (reset_signal);
794 /* Reset all trapped signals to their original values. Signals set to be
795 ignored with trap '' SIGNAL should be ignored, so we make sure that they
796 are. Called by child processes after they are forked. */
798 restore_original_signals ()
800 reset_or_restore_signal_handlers (restore_signal);
803 /* If a trap handler exists for signal SIG, then call it; otherwise just
806 maybe_call_trap_handler (sig)
809 /* Call the trap handler for SIG if the signal is trapped and not ignored. */
810 if ((sigmodes[sig] & SIG_TRAPPED) && ((sigmodes[sig] & SIG_IGNORED) == 0))
815 run_interrupt_trap ();
837 signal_is_trapped (sig)
840 return (sigmodes[sig] & SIG_TRAPPED);
844 signal_is_special (sig)
847 return (sigmodes[sig] & SIG_SPECIAL);
851 signal_is_ignored (sig)
854 return (sigmodes[sig] & SIG_IGNORED);
858 set_signal_ignored (sig)
861 sigmodes[sig] |= SIG_HARD_IGNORE;
862 original_signals[sig] = SIG_IGN;