]> git.ipfire.org Git - thirdparty/bash.git/blob - trap.c
Imported from ../bash-2.01.1.tar.gz.
[thirdparty/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, 1991 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 it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 1, or (at your option) any later
11 version.
12
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
16 for more details.
17
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, 675 Mass Ave, Cambridge, MA 02139, USA. */
21
22 #include "config.h"
23
24 #include <stdio.h>
25
26 #if defined (HAVE_UNISTD_H)
27 # include <unistd.h>
28 #endif
29
30 #include "bashtypes.h"
31 #include "trap.h"
32
33 #include "bashansi.h"
34
35 #include "shell.h"
36 #include "signames.h"
37 #include "builtins/common.h"
38
39 /* Flags which describe the current handling state of a signal. */
40 #define SIG_INHERITED 0x0 /* Value inherited from parent. */
41 #define SIG_TRAPPED 0x1 /* Currently trapped. */
42 #define SIG_HARD_IGNORE 0x2 /* Signal was ignored on shell entry. */
43 #define SIG_SPECIAL 0x4 /* Treat this signal specially. */
44 #define SIG_NO_TRAP 0x8 /* Signal cannot be trapped. */
45 #define SIG_INPROGRESS 0x10 /* Signal handler currently executing. */
46 #define SIG_CHANGED 0x20 /* Trap value changed in trap handler. */
47 #define SIG_IGNORED 0x40 /* The signal is currently being ignored. */
48
49 /* An array of such flags, one for each signal, describing what the
50 shell will do with a signal. DEBUG_TRAP == NSIG; some code below
51 assumes this. */
52 static int sigmodes[NSIG+1];
53
54 static void change_signal (), restore_signal ();
55
56 /* Variables used here but defined in other files. */
57 extern int interactive_shell, interactive;
58 extern int interrupt_immediately;
59 extern int last_command_exit_value;
60 extern int line_number;
61
62 /* The list of things to do originally, before we started trapping. */
63 SigHandler *original_signals[NSIG];
64
65 /* For each signal, a slot for a string, which is a command to be
66 executed when that signal is recieved. The slot can also contain
67 DEFAULT_SIG, which means do whatever you were going to do before
68 you were so rudely interrupted, or IGNORE_SIG, which says ignore
69 this signal. */
70 char *trap_list[NSIG+1];
71
72 /* A bitmap of signals received for which we have trap handlers. */
73 int pending_traps[NSIG];
74
75 /* Set to the number of the signal we're running the trap for + 1.
76 Used in execute_cmd.c and builtins/common.c to clean up when
77 parse_and_execute does not return normally after executing the
78 trap command (e.g., when `return' is executed in the trap command). */
79 int running_trap;
80
81 /* The value of line_number when the trap started executing, since
82 parse_and_execute resets it to 1 and the trap command might want
83 it. */
84 int trap_line_number;
85
86 /* A value which can never be the target of a trap handler. */
87 #define IMPOSSIBLE_TRAP_HANDLER (SigHandler *)initialize_traps
88
89 void
90 initialize_traps ()
91 {
92 register int i;
93
94 trap_list[EXIT_TRAP] = trap_list[DEBUG_TRAP] = (char *)NULL;
95 sigmodes[EXIT_TRAP] = sigmodes[DEBUG_TRAP] = SIG_INHERITED;
96 original_signals[EXIT_TRAP] = IMPOSSIBLE_TRAP_HANDLER;
97
98 for (i = 1; i < NSIG; i++)
99 {
100 pending_traps[i] = 0;
101 trap_list[i] = (char *)DEFAULT_SIG;
102 sigmodes[i] = SIG_INHERITED;
103 original_signals[i] = IMPOSSIBLE_TRAP_HANDLER;
104 }
105
106 /* Show which signals are treated specially by the shell. */
107 #if defined (SIGCHLD)
108 original_signals[SIGCHLD] =
109 (SigHandler *) set_signal_handler (SIGCHLD, SIG_DFL);
110 set_signal_handler (SIGCHLD, original_signals[SIGCHLD]);
111 sigmodes[SIGCHLD] |= (SIG_SPECIAL | SIG_NO_TRAP);
112 #endif /* SIGCHLD */
113
114 original_signals[SIGINT] =
115 (SigHandler *) set_signal_handler (SIGINT, SIG_DFL);
116 set_signal_handler (SIGINT, original_signals[SIGINT]);
117 sigmodes[SIGINT] |= SIG_SPECIAL;
118
119 original_signals[SIGQUIT] =
120 (SigHandler *) set_signal_handler (SIGQUIT, SIG_DFL);
121 set_signal_handler (SIGQUIT, original_signals[SIGQUIT]);
122 sigmodes[SIGQUIT] |= SIG_SPECIAL;
123
124 if (interactive)
125 {
126 original_signals[SIGTERM] =
127 (SigHandler *)set_signal_handler (SIGTERM, SIG_DFL);
128 set_signal_handler (SIGTERM, original_signals[SIGTERM]);
129 sigmodes[SIGTERM] |= SIG_SPECIAL;
130 }
131 }
132
133 /* Return the print name of this signal. */
134 char *
135 signal_name (sig)
136 int sig;
137 {
138 return ((sig > NSIG || sig < 0) ? "bad signal number" : signal_names[sig]);
139 }
140
141 /* Turn a string into a signal number, or a number into
142 a signal number. If STRING is "2", "SIGINT", or "INT",
143 then (int)2 is returned. Return NO_SIG if STRING doesn't
144 contain a valid signal descriptor. */
145 int
146 decode_signal (string)
147 char *string;
148 {
149 long sig;
150
151 if (legal_number (string, &sig))
152 return ((sig >= 0 && sig <= NSIG) ? (int)sig : NO_SIG);
153
154 /* A leading `SIG' may be omitted. */
155 for (sig = 0; sig <= NSIG; sig++)
156 if (strcasecmp (string, signal_names[sig]) == 0 ||
157 (STREQN (signal_names[sig], "SIG", 3) &&
158 strcasecmp (string, &(signal_names[sig])[3]) == 0))
159 return ((int)sig);
160
161 return (NO_SIG);
162 }
163
164 /* Non-zero when we catch a trapped signal. */
165 static int catch_flag;
166
167 void
168 run_pending_traps ()
169 {
170 register int sig;
171 int old_exit_value;
172
173 if (catch_flag == 0) /* simple optimization */
174 return;
175
176 catch_flag = 0;
177
178 /* Preserve $? when running trap. */
179 old_exit_value = last_command_exit_value;
180
181 for (sig = 1; sig < NSIG; sig++)
182 {
183 /* XXX this could be made into a counter by using
184 while (pending_traps[sig]--) instead of the if statement. */
185 if (pending_traps[sig])
186 {
187 #if defined (HAVE_POSIX_SIGNALS)
188 sigset_t set, oset;
189
190 sigemptyset (&set);
191 sigemptyset (&oset);
192
193 sigaddset (&set, sig);
194 sigprocmask (SIG_BLOCK, &set, &oset);
195 #else
196 # if defined (HAVE_BSD_SIGNALS)
197 int oldmask = sigblock (sigmask (sig));
198 # endif
199 #endif /* HAVE_POSIX_SIGNALS */
200
201 if (sig == SIGINT)
202 {
203 run_interrupt_trap ();
204 CLRINTERRUPT;
205 }
206 else
207 parse_and_execute (savestring (trap_list[sig]), "trap", SEVAL_NONINT|SEVAL_NOHIST);
208
209 pending_traps[sig] = 0;
210
211 #if defined (HAVE_POSIX_SIGNALS)
212 sigprocmask (SIG_SETMASK, &oset, (sigset_t *)NULL);
213 #else
214 # if defined (HAVE_BSD_SIGNALS)
215 sigsetmask (oldmask);
216 # endif
217 #endif /* POSIX_VERSION */
218 }
219 }
220
221 last_command_exit_value = old_exit_value;
222 }
223
224 sighandler
225 trap_handler (sig)
226 int sig;
227 {
228 if ((sig >= NSIG) ||
229 (trap_list[sig] == (char *)DEFAULT_SIG) ||
230 (trap_list[sig] == (char *)IGNORE_SIG))
231 programming_error ("trap_handler: bad signal %d", sig);
232 else
233 {
234 #if defined (MUST_REINSTALL_SIGHANDLERS)
235 set_signal_handler (sig, trap_handler);
236 #endif /* MUST_REINSTALL_SIGHANDLERS */
237
238 catch_flag = 1;
239 pending_traps[sig]++;
240
241 if (interrupt_immediately)
242 run_pending_traps ();
243 }
244
245 SIGRETURN (0);
246 }
247
248 #if defined (JOB_CONTROL) && defined (SIGCHLD)
249 /* Make COMMAND_STRING be executed when SIGCHLD is caught. */
250 void
251 set_sigchld_trap (command_string)
252 char *command_string;
253 {
254 set_signal (SIGCHLD, command_string);
255 }
256
257 /* Make COMMAND_STRING be executed when SIGCHLD is caught iff the current
258 SIGCHLD trap handler is DEFAULT_SIG. */
259 void
260 maybe_set_sigchld_trap (command_string)
261 char *command_string;
262 {
263 if ((sigmodes[SIGCHLD] & SIG_TRAPPED) == 0)
264 set_signal (SIGCHLD, command_string);
265 }
266 #endif /* JOB_CONTROL && SIGCHLD */
267
268 void
269 set_debug_trap (command)
270 char *command;
271 {
272 set_signal (DEBUG_TRAP, command);
273 }
274
275 void
276 set_sigint_trap (command)
277 char *command;
278 {
279 set_signal (SIGINT, command);
280 }
281
282 /* Reset the SIGINT handler so that subshells that are doing `shellsy'
283 things, like waiting for command substitution or executing commands
284 in explicit subshells ( ( cmd ) ), can catch interrupts properly. */
285 SigHandler *
286 set_sigint_handler ()
287 {
288 if (sigmodes[SIGINT] & SIG_HARD_IGNORE)
289 return ((SigHandler *)SIG_IGN);
290
291 else if (sigmodes[SIGINT] & SIG_IGNORED)
292 return ((SigHandler *)set_signal_handler (SIGINT, SIG_IGN)); /* XXX */
293
294 else if (sigmodes[SIGINT] & SIG_TRAPPED)
295 return ((SigHandler *)set_signal_handler (SIGINT, trap_handler));
296
297 /* The signal is not trapped, so set the handler to the shell's special
298 interrupt handler. */
299 else if (interactive) /* XXX - was interactive_shell */
300 return (set_signal_handler (SIGINT, sigint_sighandler));
301 else
302 return (set_signal_handler (SIGINT, termination_unwind_protect));
303 }
304
305 /* Return the correct handler for signal SIG according to the values in
306 sigmodes[SIG]. */
307 SigHandler *
308 trap_to_sighandler (sig)
309 int sig;
310 {
311 if (sigmodes[sig] & (SIG_IGNORED|SIG_HARD_IGNORE))
312 return (SIG_IGN);
313 else if (sigmodes[sig] & SIG_TRAPPED)
314 return (trap_handler);
315 else
316 return (SIG_DFL);
317 }
318
319 /* Set SIG to call STRING as a command. */
320 void
321 set_signal (sig, string)
322 int sig;
323 char *string;
324 {
325 if (sig == DEBUG_TRAP || sig == EXIT_TRAP)
326 {
327 change_signal (sig, savestring (string));
328 if (sig == EXIT_TRAP && interactive == 0)
329 initialize_terminating_signals ();
330 return;
331 }
332
333 /* A signal ignored on entry to the shell cannot be trapped or reset, but
334 no error is reported when attempting to do so. -- Posix.2 */
335 if (sigmodes[sig] & SIG_HARD_IGNORE)
336 return;
337
338 /* Make sure we have original_signals[sig] if the signal has not yet
339 been trapped. */
340 if ((sigmodes[sig] & SIG_TRAPPED) == 0)
341 {
342 /* If we aren't sure of the original value, check it. */
343 if (original_signals[sig] == IMPOSSIBLE_TRAP_HANDLER)
344 {
345 original_signals[sig] = (SigHandler *)set_signal_handler (sig, SIG_DFL);
346 set_signal_handler (sig, original_signals[sig]);
347 }
348
349 /* Signals ignored on entry to the shell cannot be trapped or reset. */
350 if (original_signals[sig] == SIG_IGN)
351 {
352 sigmodes[sig] |= SIG_HARD_IGNORE;
353 return;
354 }
355 }
356
357 /* Only change the system signal handler if SIG_NO_TRAP is not set.
358 The trap command string is changed in either case. The shell signal
359 handlers for SIGINT and SIGCHLD run the user specified traps in an
360 environment in which it is safe to do so. */
361 if ((sigmodes[sig] & SIG_NO_TRAP) == 0)
362 {
363 set_signal_handler (sig, SIG_IGN);
364 change_signal (sig, savestring (string));
365 set_signal_handler (sig, trap_handler);
366 }
367 else
368 change_signal (sig, savestring (string));
369 }
370
371 static void
372 free_trap_command (sig)
373 int sig;
374 {
375 if ((sigmodes[sig] & SIG_TRAPPED) && trap_list[sig] &&
376 (trap_list[sig] != (char *)IGNORE_SIG) &&
377 (trap_list[sig] != (char *)DEFAULT_SIG) &&
378 (trap_list[sig] != (char *)IMPOSSIBLE_TRAP_HANDLER))
379 free (trap_list[sig]);
380 }
381
382 /* If SIG has a string assigned to it, get rid of it. Then give it
383 VALUE. */
384 static void
385 change_signal (sig, value)
386 int sig;
387 char *value;
388 {
389 if ((sigmodes[sig] & SIG_INPROGRESS) == 0)
390 free_trap_command (sig);
391 trap_list[sig] = value;
392
393 sigmodes[sig] |= SIG_TRAPPED;
394 if (value == (char *)IGNORE_SIG)
395 sigmodes[sig] |= SIG_IGNORED;
396 else
397 sigmodes[sig] &= ~SIG_IGNORED;
398 if (sigmodes[sig] & SIG_INPROGRESS)
399 sigmodes[sig] |= SIG_CHANGED;
400 }
401
402 #define GET_ORIGINAL_SIGNAL(sig) \
403 if (sig && sig < NSIG && original_signals[sig] == IMPOSSIBLE_TRAP_HANDLER) \
404 get_original_signal (sig)
405
406 static void
407 get_original_signal (sig)
408 int sig;
409 {
410 /* If we aren't sure the of the original value, then get it. */
411 if (original_signals[sig] == (SigHandler *)IMPOSSIBLE_TRAP_HANDLER)
412 {
413 original_signals[sig] =
414 (SigHandler *) set_signal_handler (sig, SIG_DFL);
415 set_signal_handler (sig, original_signals[sig]);
416
417 /* Signals ignored on entry to the shell cannot be trapped. */
418 if (original_signals[sig] == SIG_IGN)
419 sigmodes[sig] |= SIG_HARD_IGNORE;
420 }
421 }
422
423 /* Restore the default action for SIG; i.e., the action the shell
424 would have taken before you used the trap command. This is called
425 from trap_builtin (), which takes care to restore the handlers for
426 the signals the shell treats specially. */
427 void
428 restore_default_signal (sig)
429 int sig;
430 {
431 if (sig == DEBUG_TRAP || sig == EXIT_TRAP)
432 {
433 if ((sig != DEBUG_TRAP) || (sigmodes[sig] & SIG_INPROGRESS) == 0)
434 free_trap_command (sig);
435 trap_list[sig] = (char *)NULL;
436 sigmodes[sig] &= ~SIG_TRAPPED;
437 if (sigmodes[sig] & SIG_INPROGRESS)
438 sigmodes[sig] |= SIG_CHANGED;
439 return;
440 }
441
442 GET_ORIGINAL_SIGNAL (sig);
443
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. Thanks Posix.2. */
446 if (sigmodes[sig] & SIG_HARD_IGNORE)
447 return;
448
449 /* If we aren't trapping this signal, don't bother doing anything else. */
450 if ((sigmodes[sig] & SIG_TRAPPED) == 0)
451 return;
452
453 /* Only change the signal handler for SIG if it allows it. */
454 if ((sigmodes[sig] & SIG_NO_TRAP) == 0)
455 set_signal_handler (sig, original_signals[sig]);
456
457 /* Change the trap command in either case. */
458 change_signal (sig, (char *)DEFAULT_SIG);
459
460 /* Mark the signal as no longer trapped. */
461 sigmodes[sig] &= ~SIG_TRAPPED;
462 }
463
464 /* Make this signal be ignored. */
465 void
466 ignore_signal (sig)
467 int sig;
468 {
469 if ((sig == EXIT_TRAP || sig == DEBUG_TRAP) && ((sigmodes[sig] & SIG_IGNORED) == 0))
470 {
471 change_signal (sig, (char *)IGNORE_SIG);
472 return;
473 }
474
475 GET_ORIGINAL_SIGNAL (sig);
476
477 /* A signal ignored on entry to the shell cannot be trapped or reset.
478 No error is reported when the user attempts to do so. */
479 if (sigmodes[sig] & SIG_HARD_IGNORE)
480 return;
481
482 /* If already trapped and ignored, no change necessary. */
483 if (sigmodes[sig] & SIG_IGNORED)
484 return;
485
486 /* Only change the signal handler for SIG if it allows it. */
487 if ((sigmodes[sig] & SIG_NO_TRAP) == 0)
488 set_signal_handler (sig, SIG_IGN);
489
490 /* Change the trap command in either case. */
491 change_signal (sig, (char *)IGNORE_SIG);
492 }
493
494 /* Handle the calling of "trap 0". The only sticky situation is when
495 the command to be executed includes an "exit". This is why we have
496 to provide our own place for top_level to jump to. */
497 int
498 run_exit_trap ()
499 {
500 char *trap_command;
501 int code, old_exit_value;
502
503 old_exit_value = last_command_exit_value;
504
505 /* Run the trap only if signal 0 is trapped and not ignored, and we are not
506 currently running in the trap handler (call to exit in the list of
507 commands given to trap 0). */
508 if ((sigmodes[EXIT_TRAP] & SIG_TRAPPED) &&
509 (sigmodes[EXIT_TRAP] & (SIG_IGNORED|SIG_INPROGRESS)) == 0)
510 {
511 trap_command = savestring (trap_list[EXIT_TRAP]);
512 sigmodes[EXIT_TRAP] &= ~SIG_TRAPPED;
513 sigmodes[EXIT_TRAP] |= SIG_INPROGRESS;
514
515 code = setjmp (top_level);
516
517 if (code == 0)
518 parse_and_execute (trap_command, "exit trap", SEVAL_NONINT|SEVAL_NOHIST);
519 else if (code == EXITPROG)
520 return (last_command_exit_value);
521 else
522 return (old_exit_value);
523 }
524
525 return (old_exit_value);
526 }
527
528 void
529 run_trap_cleanup (sig)
530 int sig;
531 {
532 sigmodes[sig] &= ~(SIG_INPROGRESS|SIG_CHANGED);
533 }
534
535 /* Run a trap command for SIG. SIG is one of the signals the shell treats
536 specially. */
537 static void
538 _run_trap_internal (sig, tag)
539 int sig;
540 char *tag;
541 {
542 char *trap_command, *old_trap;
543 int old_exit_value, old_line_number;
544
545 /* Run the trap only if SIG is trapped and not ignored, and we are not
546 currently executing in the trap handler. */
547 if ((sigmodes[sig] & SIG_TRAPPED) && ((sigmodes[sig] & SIG_IGNORED) == 0) &&
548 (trap_list[sig] != (char *)IMPOSSIBLE_TRAP_HANDLER) &&
549 ((sigmodes[sig] & SIG_INPROGRESS) == 0))
550 {
551 old_trap = trap_list[sig];
552 sigmodes[sig] |= SIG_INPROGRESS;
553 sigmodes[sig] &= ~SIG_CHANGED; /* just to be sure */
554 trap_command = savestring (old_trap);
555
556 running_trap = sig + 1;
557 old_exit_value = last_command_exit_value;
558 /* Need to copy the value of line_number because parse_and_execute
559 resets it to 1, and the trap command might want it. */
560 trap_line_number = line_number;
561 parse_and_execute (trap_command, tag, SEVAL_NONINT|SEVAL_NOHIST);
562 last_command_exit_value = old_exit_value;
563 running_trap = 0;
564
565 sigmodes[sig] &= ~SIG_INPROGRESS;
566
567 if (sigmodes[sig] & SIG_CHANGED)
568 {
569 free (old_trap);
570 sigmodes[sig] &= ~SIG_CHANGED;
571 }
572 }
573 }
574
575 void
576 run_debug_trap ()
577 {
578 if ((sigmodes[DEBUG_TRAP] & SIG_TRAPPED) && (sigmodes[DEBUG_TRAP] & SIG_INPROGRESS) == 0)
579 _run_trap_internal (DEBUG_TRAP, "debug trap");
580 }
581
582 /* Run a trap set on SIGINT. This is called from throw_to_top_level (), and
583 declared here to localize the trap functions. */
584 void
585 run_interrupt_trap ()
586 {
587 _run_trap_internal (SIGINT, "interrupt trap");
588 }
589
590 /* Free all the allocated strings in the list of traps and reset the trap
591 values to the default. */
592 void
593 free_trap_strings ()
594 {
595 register int i;
596
597 for (i = 0; i < NSIG+1; i++)
598 {
599 free_trap_command (i);
600 trap_list[i] = (char *)DEFAULT_SIG;
601 sigmodes[i] &= ~SIG_TRAPPED;
602 }
603 trap_list[DEBUG_TRAP] = trap_list[EXIT_TRAP] = (char *)NULL;
604 }
605
606 /* Reset the handler for SIG to the original value. */
607 static void
608 reset_signal (sig)
609 int sig;
610 {
611 set_signal_handler (sig, original_signals[sig]);
612 }
613
614 /* Set the handler signal SIG to the original and free any trap
615 command associated with it. */
616 static void
617 restore_signal (sig)
618 int sig;
619 {
620 set_signal_handler (sig, original_signals[sig]);
621 change_signal (sig, (char *)DEFAULT_SIG);
622 sigmodes[sig] &= ~SIG_TRAPPED;
623 }
624
625 static void
626 reset_or_restore_signal_handlers (reset)
627 VFunction *reset;
628 {
629 register int i;
630
631 /* Take care of the exit trap first */
632 if (sigmodes[EXIT_TRAP] & SIG_TRAPPED)
633 {
634 free_trap_command (EXIT_TRAP);
635 trap_list[EXIT_TRAP] = (char *)NULL;
636 sigmodes[EXIT_TRAP] &= ~SIG_TRAPPED;
637 }
638 for (i = 1; i < NSIG; i++)
639 {
640 if (sigmodes[i] & SIG_TRAPPED)
641 {
642 if (trap_list[i] == (char *)IGNORE_SIG)
643 set_signal_handler (i, SIG_IGN);
644 else
645 (*reset) (i);
646 }
647 else if (sigmodes[i] & SIG_SPECIAL)
648 (*reset) (i);
649 }
650 }
651
652 void
653 reset_signal_handlers ()
654 {
655 reset_or_restore_signal_handlers (reset_signal);
656 }
657
658 /* Reset all trapped signals to their original values. Signals set to be
659 ignored with trap '' SIGNAL should be ignored, so we make sure that they
660 are. Called by child processes after they are forked. */
661 void
662 restore_original_signals ()
663 {
664 reset_or_restore_signal_handlers (restore_signal);
665 }
666
667 /* If a trap handler exists for signal SIG, then call it; otherwise just
668 return failure. */
669 int
670 maybe_call_trap_handler (sig)
671 int sig;
672 {
673 /* Call the trap handler for SIG if the signal is trapped and not ignored. */
674 if ((sigmodes[sig] & SIG_TRAPPED) && ((sigmodes[sig] & SIG_IGNORED) == 0))
675 {
676 switch (sig)
677 {
678 case SIGINT:
679 run_interrupt_trap ();
680 break;
681 case EXIT_TRAP:
682 run_exit_trap ();
683 break;
684 case DEBUG_TRAP:
685 run_debug_trap ();
686 break;
687 default:
688 trap_handler (sig);
689 break;
690 }
691 return (1);
692 }
693 else
694 return (0);
695 }
696
697 int
698 signal_is_trapped (sig)
699 int sig;
700 {
701 return (sigmodes[sig] & SIG_TRAPPED);
702 }
703
704 int
705 signal_is_special (sig)
706 int sig;
707 {
708 return (sigmodes[sig] & SIG_SPECIAL);
709 }
710
711 int
712 signal_is_ignored (sig)
713 int sig;
714 {
715 return (sigmodes[sig] & SIG_IGNORED);
716 }
717
718 void
719 set_signal_ignored (sig)
720 int sig;
721 {
722 sigmodes[sig] |= SIG_HARD_IGNORE;
723 original_signals[sig] = SIG_IGN;
724 }