Home | History | Annotate | Line # | Download | only in ksh
      1  1.14     kamil /*	$NetBSD: trap.c,v 1.14 2018/05/08 16:37:59 kamil Exp $	*/
      2   1.2       tls 
      3   1.1       jtc /*
      4   1.1       jtc  * signal handling
      5   1.1       jtc  */
      6   1.5       agc #include <sys/cdefs.h>
      7   1.5       agc 
      8   1.5       agc #ifndef lint
      9  1.14     kamil __RCSID("$NetBSD: trap.c,v 1.14 2018/05/08 16:37:59 kamil Exp $");
     10   1.5       agc #endif
     11   1.5       agc 
     12   1.1       jtc #include "sh.h"
     13   1.1       jtc 
     14   1.1       jtc /* Table is indexed by signal number
     15   1.1       jtc  *
     16   1.1       jtc  * The script siglist.sh generates siglist.out, which is a sorted, complete
     17   1.1       jtc  * list of signals
     18   1.1       jtc  */
     19   1.1       jtc Trap sigtraps[SIGNALS+1] = {
     20   1.8  christos 	{ .signal = SIGEXIT_, .name = "EXIT", .mess = "Signal 0" },
     21   1.1       jtc #include "siglist.out"	/* generated by siglist.sh */
     22   1.8  christos 	{ .signal = SIGERR_,  .name = "ERR",  .mess = "Error handler" },
     23   1.1       jtc     };
     24   1.1       jtc 
     25   1.1       jtc static struct sigaction Sigact_ign, Sigact_trap;
     26   1.1       jtc 
     27   1.1       jtc void
     28   1.1       jtc inittraps()
     29   1.1       jtc {
     30   1.1       jtc #ifdef HAVE_SYS_SIGLIST
     31   1.1       jtc # ifndef SYS_SIGLIST_DECLARED
     32   1.1       jtc 	extern char	*sys_siglist[];
     33   1.1       jtc # endif
     34   1.1       jtc 	int	i;
     35   1.1       jtc 
     36   1.1       jtc 	/* Use system description, if available, for unknown signals... */
     37   1.1       jtc 	for (i = 0; i < NSIG; i++)
     38   1.3   hubertf 		if (!sigtraps[i].name && sys_siglist[i] && sys_siglist[i][0])
     39   1.1       jtc 			sigtraps[i].mess = sys_siglist[i];
     40   1.1       jtc #endif	/* HAVE_SYS_SIGLIST */
     41   1.1       jtc 
     42   1.1       jtc 	sigemptyset(&Sigact_ign.sa_mask);
     43   1.1       jtc 	Sigact_ign.sa_flags = KSH_SA_FLAGS;
     44   1.1       jtc 	Sigact_ign.sa_handler = SIG_IGN;
     45   1.1       jtc 	Sigact_trap = Sigact_ign;
     46   1.1       jtc 	Sigact_trap.sa_handler = trapsig;
     47   1.1       jtc 
     48   1.1       jtc 	sigtraps[SIGINT].flags |= TF_DFL_INTR | TF_TTY_INTR;
     49   1.1       jtc 	sigtraps[SIGQUIT].flags |= TF_DFL_INTR | TF_TTY_INTR;
     50   1.1       jtc 	sigtraps[SIGTERM].flags |= TF_DFL_INTR;/* not fatal for interactive */
     51   1.1       jtc 	sigtraps[SIGHUP].flags |= TF_FATAL;
     52   1.1       jtc 	sigtraps[SIGCHLD].flags |= TF_SHELL_USES;
     53   1.1       jtc 
     54   1.6   mycroft 	/* these are always caught so we can clean up any temporary files. */
     55   1.1       jtc 	setsig(&sigtraps[SIGINT], trapsig, SS_RESTORE_ORIG);
     56   1.1       jtc 	setsig(&sigtraps[SIGQUIT], trapsig, SS_RESTORE_ORIG);
     57   1.1       jtc 	setsig(&sigtraps[SIGTERM], trapsig, SS_RESTORE_ORIG);
     58   1.1       jtc 	setsig(&sigtraps[SIGHUP], trapsig, SS_RESTORE_ORIG);
     59   1.1       jtc }
     60   1.1       jtc 
     61   1.1       jtc #ifdef KSH
     62   1.1       jtc static RETSIGTYPE alarm_catcher ARGS((int sig));
     63   1.1       jtc 
     64   1.1       jtc void
     65   1.1       jtc alarm_init()
     66   1.1       jtc {
     67   1.1       jtc 	sigtraps[SIGALRM].flags |= TF_SHELL_USES;
     68   1.1       jtc 	setsig(&sigtraps[SIGALRM], alarm_catcher,
     69   1.1       jtc 		SS_RESTORE_ORIG|SS_FORCE|SS_SHTRAP);
     70   1.1       jtc }
     71   1.1       jtc 
     72   1.1       jtc static RETSIGTYPE
     73   1.1       jtc alarm_catcher(sig)
     74   1.1       jtc 	int sig;
     75   1.1       jtc {
     76   1.6   mycroft 	int errno_ = errno;
     77   1.6   mycroft 
     78   1.1       jtc 	if (ksh_tmout_state == TMOUT_READING) {
     79   1.1       jtc 		int left = alarm(0);
     80   1.1       jtc 
     81   1.1       jtc 		if (left == 0) {
     82   1.1       jtc 			ksh_tmout_state = TMOUT_LEAVING;
     83   1.1       jtc 			intrsig = 1;
     84   1.1       jtc 		} else
     85   1.1       jtc 			alarm(left);
     86   1.1       jtc 	}
     87   1.6   mycroft 	errno = errno_;
     88   1.1       jtc 	return RETSIGVAL;
     89   1.1       jtc }
     90   1.1       jtc #endif /* KSH */
     91   1.1       jtc 
     92   1.1       jtc Trap *
     93   1.3   hubertf gettrap(name, igncase)
     94   1.1       jtc 	const char *name;
     95   1.3   hubertf 	int igncase;
     96   1.1       jtc {
     97   1.1       jtc 	int i;
     98  1.14     kamil 	Trap *p;
     99   1.1       jtc 
    100   1.1       jtc 	if (digit(*name)) {
    101   1.1       jtc 		int n;
    102   1.1       jtc 
    103   1.1       jtc 		if (getn(name, &n) && 0 <= n && n < SIGNALS)
    104   1.1       jtc 			return &sigtraps[n];
    105   1.1       jtc 		return NULL;
    106   1.1       jtc 	}
    107   1.1       jtc 	for (p = sigtraps, i = SIGNALS+1; --i >= 0; p++)
    108   1.6   mycroft 		if (p->name) {
    109   1.6   mycroft 			if (igncase) {
    110   1.6   mycroft 				if (p->name && (!strcasecmp(p->name, name) ||
    111   1.6   mycroft 				    (strlen(name) > 3 && !strncasecmp("SIG",
    112   1.6   mycroft 				    p->name, 3) &&
    113   1.6   mycroft 				    !strcasecmp(p->name, name + 3))))
    114   1.6   mycroft 					return p;
    115   1.6   mycroft 			} else {
    116   1.6   mycroft 				if (p->name && (!strcmp(p->name, name) ||
    117   1.6   mycroft 				    (strlen(name) > 3 && !strncmp("SIG",
    118   1.6   mycroft 				    p->name, 3) && !strcmp(p->name, name + 3))))
    119   1.6   mycroft 					return p;
    120   1.6   mycroft 			}
    121   1.6   mycroft 		}
    122   1.1       jtc 	return NULL;
    123   1.1       jtc }
    124   1.1       jtc 
    125   1.1       jtc /*
    126   1.1       jtc  * trap signal handler
    127   1.1       jtc  */
    128   1.1       jtc RETSIGTYPE
    129   1.1       jtc trapsig(i)
    130   1.1       jtc 	int i;
    131   1.1       jtc {
    132   1.1       jtc 	Trap *p = &sigtraps[i];
    133   1.6   mycroft 	int errno_ = errno;
    134   1.1       jtc 
    135   1.1       jtc 	trap = p->set = 1;
    136   1.1       jtc 	if (p->flags & TF_DFL_INTR)
    137   1.1       jtc 		intrsig = 1;
    138   1.1       jtc 	if ((p->flags & TF_FATAL) && !p->trap) {
    139   1.1       jtc 		fatal_trap = 1;
    140   1.1       jtc 		intrsig = 1;
    141   1.1       jtc 	}
    142   1.1       jtc 	if (p->shtrap)
    143   1.1       jtc 		(*p->shtrap)(i);
    144  1.12     kamil 
    145   1.6   mycroft 	errno = errno_;
    146   1.1       jtc 	return RETSIGVAL;
    147   1.1       jtc }
    148   1.1       jtc 
    149   1.1       jtc /* called when we want to allow the user to ^C out of something - won't
    150   1.1       jtc  * work if user has trapped SIGINT.
    151   1.1       jtc  */
    152   1.1       jtc void
    153   1.1       jtc intrcheck()
    154   1.1       jtc {
    155   1.1       jtc 	if (intrsig)
    156   1.1       jtc 		runtraps(TF_DFL_INTR|TF_FATAL);
    157   1.1       jtc }
    158   1.1       jtc 
    159   1.1       jtc /* called after EINTR to check if a signal with normally causes process
    160   1.1       jtc  * termination has been received.
    161   1.1       jtc  */
    162   1.1       jtc int
    163   1.1       jtc fatal_trap_check()
    164   1.1       jtc {
    165   1.1       jtc 	int i;
    166   1.1       jtc 	Trap *p;
    167   1.1       jtc 
    168   1.1       jtc 	/* todo: should check if signal is fatal, not the TF_DFL_INTR flag */
    169   1.1       jtc 	for (p = sigtraps, i = SIGNALS+1; --i >= 0; p++)
    170   1.1       jtc 		if (p->set && (p->flags & (TF_DFL_INTR|TF_FATAL)))
    171   1.1       jtc 			/* return value is used as an exit code */
    172   1.1       jtc 			return 128 + p->signal;
    173   1.1       jtc 	return 0;
    174   1.1       jtc }
    175   1.1       jtc 
    176   1.1       jtc /* Returns the signal number of any pending traps: ie, a signal which has
    177   1.4       wiz  * occurred for which a trap has been set or for which the TF_DFL_INTR flag
    178   1.1       jtc  * is set.
    179   1.1       jtc  */
    180   1.1       jtc int
    181   1.1       jtc trap_pending()
    182   1.1       jtc {
    183   1.1       jtc 	int i;
    184   1.1       jtc 	Trap *p;
    185   1.1       jtc 
    186   1.1       jtc 	for (p = sigtraps, i = SIGNALS+1; --i >= 0; p++)
    187   1.1       jtc 		if (p->set && ((p->trap && p->trap[0])
    188   1.1       jtc 			       || ((p->flags & (TF_DFL_INTR|TF_FATAL))
    189   1.1       jtc 				   && !p->trap)))
    190   1.1       jtc 			return p->signal;
    191   1.1       jtc 	return 0;
    192   1.1       jtc }
    193   1.1       jtc 
    194   1.1       jtc /*
    195   1.1       jtc  * run any pending traps.  If intr is set, only run traps that
    196   1.1       jtc  * can interrupt commands.
    197   1.1       jtc  */
    198   1.1       jtc void
    199   1.1       jtc runtraps(flag)
    200   1.1       jtc 	int flag;
    201   1.1       jtc {
    202   1.1       jtc 	int i;
    203  1.14     kamil 	Trap *p;
    204   1.1       jtc 
    205   1.1       jtc #ifdef KSH
    206   1.1       jtc 	if (ksh_tmout_state == TMOUT_LEAVING) {
    207   1.1       jtc 		ksh_tmout_state = TMOUT_EXECUTING;
    208  1.13     kamil 		warningf(false, "timed out waiting for input");
    209   1.1       jtc 		unwind(LEXIT);
    210   1.1       jtc 	} else
    211   1.1       jtc 		/* XXX: this means the alarm will have no effect if a trap
    212   1.1       jtc 		 * is caught after the alarm() was started...not good.
    213   1.1       jtc 		 */
    214   1.1       jtc 		ksh_tmout_state = TMOUT_EXECUTING;
    215   1.1       jtc #endif /* KSH */
    216   1.1       jtc 	if (!flag)
    217   1.1       jtc 		trap = 0;
    218   1.1       jtc 	if (flag & TF_DFL_INTR)
    219   1.1       jtc 		intrsig = 0;
    220   1.1       jtc 	if (flag & TF_FATAL)
    221   1.1       jtc 		fatal_trap = 0;
    222   1.1       jtc 	for (p = sigtraps, i = SIGNALS+1; --i >= 0; p++)
    223   1.1       jtc 		if (p->set && (!flag
    224   1.1       jtc 			       || ((p->flags & flag) && p->trap == (char *) 0)))
    225   1.1       jtc 			runtrap(p);
    226   1.1       jtc }
    227   1.1       jtc 
    228   1.1       jtc void
    229   1.1       jtc runtrap(p)
    230   1.1       jtc 	Trap *p;
    231   1.1       jtc {
    232   1.1       jtc 	int	i = p->signal;
    233   1.1       jtc 	char	*trapstr = p->trap;
    234   1.1       jtc 	int	oexstat;
    235   1.1       jtc 	int	UNINITIALIZED(old_changed);
    236   1.1       jtc 
    237   1.1       jtc 	p->set = 0;
    238   1.1       jtc 	if (trapstr == (char *) 0) { /* SIG_DFL */
    239   1.1       jtc 		if (p->flags & TF_FATAL) {
    240   1.1       jtc 			/* eg, SIGHUP */
    241   1.1       jtc 			exstat = 128 + i;
    242   1.1       jtc 			unwind(LLEAVE);
    243   1.1       jtc 		}
    244   1.1       jtc 		if (p->flags & TF_DFL_INTR) {
    245   1.1       jtc 			/* eg, SIGINT, SIGQUIT, SIGTERM, etc. */
    246   1.1       jtc 			exstat = 128 + i;
    247   1.1       jtc 			unwind(LINTR);
    248   1.1       jtc 		}
    249   1.1       jtc 		return;
    250   1.1       jtc 	}
    251   1.1       jtc 	if (trapstr[0] == '\0') /* SIG_IGN */
    252   1.1       jtc 		return;
    253   1.1       jtc 	if (i == SIGEXIT_ || i == SIGERR_) {	/* avoid recursion on these */
    254   1.1       jtc 		old_changed = p->flags & TF_CHANGED;
    255   1.1       jtc 		p->flags &= ~TF_CHANGED;
    256   1.1       jtc 		p->trap = (char *) 0;
    257   1.1       jtc 	}
    258   1.1       jtc 	oexstat = exstat;
    259   1.3   hubertf 	/* Note: trapstr is fully parsed before anything is executed, thus
    260   1.3   hubertf 	 * no problem with afree(p->trap) in settrap() while still in use.
    261   1.3   hubertf 	 */
    262   1.1       jtc 	command(trapstr);
    263   1.1       jtc 	exstat = oexstat;
    264   1.1       jtc 	if (i == SIGEXIT_ || i == SIGERR_) {
    265   1.1       jtc 		if (p->flags & TF_CHANGED)
    266   1.1       jtc 			/* don't clear TF_CHANGED */
    267   1.1       jtc 			afree(trapstr, APERM);
    268   1.1       jtc 		else
    269   1.1       jtc 			p->trap = trapstr;
    270   1.1       jtc 		p->flags |= old_changed;
    271   1.1       jtc 	}
    272   1.1       jtc }
    273   1.6   mycroft 
    274   1.1       jtc /* clear pending traps and reset user's trap handlers; used after fork(2) */
    275   1.1       jtc void
    276   1.1       jtc cleartraps()
    277   1.1       jtc {
    278   1.1       jtc 	int i;
    279   1.1       jtc 	Trap *p;
    280   1.1       jtc 
    281   1.1       jtc 	trap = 0;
    282   1.1       jtc 	intrsig = 0;
    283   1.1       jtc 	fatal_trap = 0;
    284   1.1       jtc 	for (i = SIGNALS+1, p = sigtraps; --i >= 0; p++) {
    285   1.1       jtc 		p->set = 0;
    286   1.1       jtc 		if ((p->flags & TF_USER_SET) && (p->trap && p->trap[0]))
    287   1.1       jtc 			settrap(p, (char *) 0);
    288   1.1       jtc 	}
    289   1.1       jtc }
    290   1.1       jtc 
    291   1.1       jtc /* restore signals just before an exec(2) */
    292   1.1       jtc void
    293   1.1       jtc restoresigs()
    294   1.1       jtc {
    295   1.1       jtc 	int i;
    296   1.1       jtc 	Trap *p;
    297   1.1       jtc 
    298   1.1       jtc 	for (i = SIGNALS+1, p = sigtraps; --i >= 0; p++)
    299   1.1       jtc 		if (p->flags & (TF_EXEC_IGN|TF_EXEC_DFL))
    300   1.1       jtc 			setsig(p, (p->flags & TF_EXEC_IGN) ? SIG_IGN : SIG_DFL,
    301   1.1       jtc 				SS_RESTORE_CURR|SS_FORCE);
    302   1.1       jtc }
    303   1.1       jtc 
    304   1.1       jtc void
    305   1.1       jtc settrap(p, s)
    306   1.1       jtc 	Trap *p;
    307   1.1       jtc 	char *s;
    308   1.1       jtc {
    309   1.1       jtc 	handler_t f;
    310   1.1       jtc 
    311   1.1       jtc 	if (p->trap)
    312   1.1       jtc 		afree(p->trap, APERM);
    313   1.7  christos 	p->flags |= TF_CHANGED|TF_USER_SET;
    314   1.7  christos 	if (s) {
    315   1.7  christos 		p->trap = str_save(s, APERM);
    316   1.7  christos 		f = s[0] ? trapsig : SIG_IGN;
    317   1.7  christos 	} else {
    318   1.7  christos 		p->trap = NULL;
    319   1.7  christos 		f = SIG_DFL;
    320   1.7  christos 	}
    321   1.1       jtc 	if ((p->flags & (TF_DFL_INTR|TF_FATAL)) && f == SIG_DFL)
    322   1.1       jtc 		f = trapsig;
    323   1.1       jtc 	else if (p->flags & TF_SHELL_USES) {
    324   1.1       jtc 		if (!(p->flags & TF_ORIG_IGN) || Flag(FTALKING)) {
    325   1.1       jtc 			/* do what user wants at exec time */
    326   1.1       jtc 			p->flags &= ~(TF_EXEC_IGN|TF_EXEC_DFL);
    327   1.1       jtc 			if (f == SIG_IGN)
    328   1.1       jtc 				p->flags |= TF_EXEC_IGN;
    329   1.1       jtc 			else
    330   1.1       jtc 				p->flags |= TF_EXEC_DFL;
    331   1.1       jtc 		}
    332   1.1       jtc 		/* assumes handler already set to what shell wants it
    333   1.1       jtc 		 * (normally trapsig, but could be j_sigchld() or SIG_IGN)
    334   1.1       jtc 		 */
    335   1.1       jtc 		return;
    336   1.1       jtc 	}
    337   1.1       jtc 
    338   1.1       jtc 	/* todo: should we let user know signal is ignored? how? */
    339   1.1       jtc 	setsig(p, f, SS_RESTORE_CURR|SS_USER);
    340   1.1       jtc }
    341   1.1       jtc 
    342   1.1       jtc /* Called by c_print() when writing to a co-process to ensure SIGPIPE won't
    343   1.1       jtc  * kill shell (unless user catches it and exits)
    344   1.1       jtc  */
    345   1.1       jtc int
    346   1.1       jtc block_pipe()
    347   1.1       jtc {
    348   1.1       jtc 	int restore_dfl = 0;
    349   1.1       jtc 	Trap *p = &sigtraps[SIGPIPE];
    350   1.1       jtc 
    351   1.1       jtc 	if (!(p->flags & (TF_ORIG_IGN|TF_ORIG_DFL))) {
    352   1.1       jtc 		setsig(p, SIG_IGN, SS_RESTORE_CURR);
    353   1.1       jtc 		if (p->flags & TF_ORIG_DFL)
    354   1.1       jtc 			restore_dfl = 1;
    355   1.1       jtc 	} else if (p->cursig == SIG_DFL) {
    356   1.1       jtc 		setsig(p, SIG_IGN, SS_RESTORE_CURR);
    357   1.1       jtc 		restore_dfl = 1; /* restore to SIG_DFL */
    358   1.1       jtc 	}
    359   1.1       jtc 	return restore_dfl;
    360   1.1       jtc }
    361   1.1       jtc 
    362   1.1       jtc /* Called by c_print() to undo whatever block_pipe() did */
    363   1.1       jtc void
    364   1.1       jtc restore_pipe(restore_dfl)
    365   1.1       jtc 	int restore_dfl;
    366   1.1       jtc {
    367   1.1       jtc 	if (restore_dfl)
    368   1.1       jtc 		setsig(&sigtraps[SIGPIPE], SIG_DFL, SS_RESTORE_CURR);
    369   1.1       jtc }
    370   1.1       jtc 
    371   1.1       jtc /* Set action for a signal.  Action may not be set if original
    372   1.1       jtc  * action was SIG_IGN, depending on the value of flags and
    373   1.1       jtc  * FTALKING.
    374   1.1       jtc  */
    375   1.1       jtc int
    376   1.1       jtc setsig(p, f, flags)
    377   1.1       jtc 	Trap *p;
    378   1.1       jtc 	handler_t f;
    379   1.1       jtc 	int flags;
    380   1.1       jtc {
    381   1.1       jtc 	struct sigaction sigact;
    382   1.1       jtc 
    383   1.1       jtc 	if (p->signal == SIGEXIT_ || p->signal == SIGERR_)
    384   1.1       jtc 		return 1;
    385   1.1       jtc 
    386   1.1       jtc 	/* First time setting this signal?  If so, get and note the current
    387   1.1       jtc 	 * setting.
    388   1.1       jtc 	 */
    389   1.1       jtc 	if (!(p->flags & (TF_ORIG_IGN|TF_ORIG_DFL))) {
    390   1.1       jtc 		sigaction(p->signal, &Sigact_ign, &sigact);
    391   1.1       jtc 		p->flags |= sigact.sa_handler == SIG_IGN ?
    392   1.1       jtc 					TF_ORIG_IGN : TF_ORIG_DFL;
    393   1.1       jtc 		p->cursig = SIG_IGN;
    394   1.1       jtc 	}
    395   1.1       jtc 
    396   1.1       jtc 	/* Generally, an ignored signal stays ignored, except if
    397   1.1       jtc 	 *	- the user of an interactive shell wants to change it
    398   1.1       jtc 	 *	- the shell wants for force a change
    399   1.1       jtc 	 */
    400   1.1       jtc 	if ((p->flags & TF_ORIG_IGN) && !(flags & SS_FORCE)
    401   1.1       jtc 	    && (!(flags & SS_USER) || !Flag(FTALKING)))
    402   1.1       jtc 		return 0;
    403   1.1       jtc 
    404   1.1       jtc 	setexecsig(p, flags & SS_RESTORE_MASK);
    405   1.1       jtc 
    406   1.1       jtc 	/* This is here 'cause there should be a way of clearing shtraps, but
    407   1.1       jtc 	 * don't know if this is a sane way of doing it.  At the moment,
    408   1.1       jtc 	 * all users of shtrap are lifetime users (SIGCHLD, SIGALRM, SIGWINCH).
    409   1.1       jtc 	 */
    410   1.1       jtc 	if (!(flags & SS_USER))
    411   1.1       jtc 		p->shtrap = (handler_t) 0;
    412   1.1       jtc 	if (flags & SS_SHTRAP) {
    413   1.1       jtc 		p->shtrap = f;
    414   1.1       jtc 		f = trapsig;
    415   1.1       jtc 	}
    416   1.1       jtc 
    417   1.1       jtc 	if (p->cursig != f) {
    418   1.1       jtc 		p->cursig = f;
    419   1.1       jtc 		sigemptyset(&sigact.sa_mask);
    420   1.1       jtc 		sigact.sa_flags = KSH_SA_FLAGS;
    421   1.1       jtc 		sigact.sa_handler = f;
    422   1.1       jtc 		sigaction(p->signal, &sigact, (struct sigaction *) 0);
    423   1.1       jtc 	}
    424   1.1       jtc 
    425   1.1       jtc 	return 1;
    426   1.1       jtc }
    427   1.1       jtc 
    428   1.1       jtc /* control what signal is set to before an exec() */
    429   1.1       jtc void
    430   1.1       jtc setexecsig(p, restore)
    431   1.1       jtc 	Trap *p;
    432   1.1       jtc 	int restore;
    433   1.1       jtc {
    434   1.1       jtc 	/* XXX debugging */
    435   1.1       jtc 	if (!(p->flags & (TF_ORIG_IGN|TF_ORIG_DFL)))
    436   1.1       jtc 		internal_errorf(1, "setexecsig: unset signal %d(%s)",
    437   1.1       jtc 			p->signal, p->name);
    438   1.1       jtc 
    439   1.1       jtc 	/* restore original value for exec'd kids */
    440   1.1       jtc 	p->flags &= ~(TF_EXEC_IGN|TF_EXEC_DFL);
    441   1.1       jtc 	switch (restore & SS_RESTORE_MASK) {
    442   1.1       jtc 	  case SS_RESTORE_CURR: /* leave things as they currently are */
    443   1.1       jtc 		break;
    444   1.1       jtc 	  case SS_RESTORE_ORIG:
    445   1.1       jtc 		p->flags |= p->flags & TF_ORIG_IGN ? TF_EXEC_IGN : TF_EXEC_DFL;
    446   1.1       jtc 		break;
    447   1.1       jtc 	  case SS_RESTORE_DFL:
    448   1.1       jtc 		p->flags |= TF_EXEC_DFL;
    449   1.1       jtc 		break;
    450   1.1       jtc 	  case SS_RESTORE_IGN:
    451   1.1       jtc 		p->flags |= TF_EXEC_IGN;
    452   1.1       jtc 		break;
    453   1.1       jtc 	}
    454   1.1       jtc }
    455