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