1/*- 2 * Copyright (c) 1991, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Kenneth Almquist. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 25 unchanged lines hidden (view full) --- 34 * SUCH DAMAGE. 35 */ 36 37#ifndef lint 38#if 0 39static char sccsid[] = "@(#)trap.c 8.5 (Berkeley) 6/5/95"; 40#endif 41static const char rcsid[] = |
42 "$FreeBSD: head/bin/sh/trap.c 90111 2002-02-02 06:50:57Z imp $"; |
43#endif /* not lint */ 44 45#include <signal.h> 46#include <unistd.h> 47#include <stdlib.h> 48 49#include "shell.h" 50#include "main.h" --- 26 unchanged lines hidden (view full) --- 77MKINIT char sigmode[NSIG]; /* current value of signal */ 78int pendingsigs; /* indicates some signal received */ 79int in_dotrap; /* do we execute in a trap handler? */ 80static char *volatile trap[NSIG]; /* trap handler commands */ 81static volatile sig_atomic_t gotsig[NSIG]; 82 /* indicates specified signal received */ 83static int ignore_sigchld; /* Used while handling SIGCHLD traps. */ 84 |
85static int getsigaction(int, sig_t *); |
86 87 88/* 89 * Map a string to a signal number. 90 */ 91static int |
92sigstring_to_signum(char *sig) |
93{ 94 95 if (is_number(sig)) { 96 int signo; 97 98 signo = atoi(sig); 99 return ((signo >= 0 && signo < NSIG) ? signo : (-1)); 100 } else if (strcasecmp(sig, "exit") == 0) { --- 10 unchanged lines hidden (view full) --- 111 return (-1); 112} 113 114 115/* 116 * Print a list of valid signal names. 117 */ 118static void |
119printsignals(void) |
120{ 121 int n; 122 123 for (n = 1; n < NSIG; n++) { 124 out1fmt("%s", sys_signame[n]); 125 if (n == (NSIG / 2) || n == (NSIG - 1)) 126 out1str("\n"); 127 else 128 out1c(' '); 129 } 130} 131 132 133/* 134 * The trap builtin. 135 */ 136int |
137trapcmd(int argc, char **argv) |
138{ 139 char *action; 140 int signo; 141 142 if (argc <= 1) { 143 for (signo = 0 ; signo < NSIG ; signo++) { 144 if (trap[signo] != NULL) 145 out1fmt("trap -- '%s' %s\n", trap[signo], --- 34 unchanged lines hidden (view full) --- 180 return 0; 181} 182 183 184/* 185 * Clear traps on a fork. 186 */ 187void |
188clear_traps(void) |
189{ 190 char *volatile *tp; 191 192 for (tp = trap ; tp <= &trap[NSIG - 1] ; tp++) { 193 if (*tp && **tp) { /* trap not NULL or SIG_IGN */ 194 INTOFF; 195 ckfree(*tp); 196 *tp = NULL; --- 5 unchanged lines hidden (view full) --- 202} 203 204 205/* 206 * Set the signal handler for the specified signal. The routine figures 207 * out what it should be set to. 208 */ 209void |
210setsignal(int signo) |
211{ 212 int action; 213 sig_t sig, sigact = SIG_DFL; 214 char *t; 215 216 if ((t = trap[signo]) == NULL) 217 action = S_DFL; 218 else if (*t != '\0') --- 68 unchanged lines hidden (view full) --- 287#endif 288} 289 290 291/* 292 * Return the current setting for sig w/o changing it. 293 */ 294static int |
295getsigaction(int signo, sig_t *sigact) |
296{ 297 struct sigaction sa; 298 299 if (sigaction(signo, (struct sigaction *)0, &sa) == -1) 300 return 0; 301 *sigact = (sig_t) sa.sa_handler; 302 return 1; 303} 304 305 306/* 307 * Ignore a signal. 308 */ 309void |
310ignoresig(int signo) |
311{ 312 313 if (sigmode[signo] != S_IGN && sigmode[signo] != S_HARD_IGN) { 314 signal(signo, SIG_IGN); 315 } 316 sigmode[signo] = S_HARD_IGN; 317} 318 --- 13 unchanged lines hidden (view full) --- 332} 333#endif 334 335 336/* 337 * Signal handler. 338 */ 339void |
340onsig(int signo) |
341{ 342 343#ifndef BSD 344 signal(signo, onsig); 345#endif 346 if (signo == SIGINT && trap[SIGINT] == NULL) { 347 onint(); 348 return; --- 18 unchanged lines hidden (view full) --- 367} 368 369 370/* 371 * Called to execute a trap. Perhaps we should avoid entering new trap 372 * handlers while we are executing a trap handler. 373 */ 374void |
375dotrap(void) |
376{ 377 int i; 378 int savestatus; 379 380 in_dotrap++; 381 for (;;) { 382 for (i = 1; i < NSIG; i++) { 383 if (gotsig[i]) { --- 21 unchanged lines hidden (view full) --- 405 pendingsigs = 0; 406} 407 408 409/* 410 * Controls whether the shell is interactive or not. 411 */ 412void |
413setinteractive(int on) |
414{ 415 static int is_interactive = -1; 416 417 if (on == is_interactive) 418 return; 419 setsignal(SIGINT); 420 setsignal(SIGQUIT); 421 setsignal(SIGTERM); 422 is_interactive = on; 423} 424 425 426/* 427 * Called to exit the shell. 428 */ 429void |
430exitshell(int status) |
431{ 432 struct jmploc loc1, loc2; 433 char *p; 434 435 TRACE(("exitshell(%d) pid=%d\n", status, getpid())); 436 if (setjmp(loc1.loc)) { 437 goto l1; 438 } --- 15 unchanged lines hidden --- |