xref: /titanic_51/usr/src/cmd/sh/fault.c (revision 965005c81e0f731867d47892b9fb677030b102df)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
57c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
67c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
77c478bd9Sstevel@tonic-gate  * with the License.
87c478bd9Sstevel@tonic-gate  *
97c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
107c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
117c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
127c478bd9Sstevel@tonic-gate  * and limitations under the License.
137c478bd9Sstevel@tonic-gate  *
147c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
157c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
167c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
177c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
187c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
197c478bd9Sstevel@tonic-gate  *
207c478bd9Sstevel@tonic-gate  * CDDL HEADER END
217c478bd9Sstevel@tonic-gate  */
22*965005c8Schin 
23*965005c8Schin /*
24*965005c8Schin  * Copyright 1997 Sun Microsystems, Inc.  All rights reserved.
25*965005c8Schin  * Use is subject to license terms.
26*965005c8Schin  */
27*965005c8Schin 
287c478bd9Sstevel@tonic-gate /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
297c478bd9Sstevel@tonic-gate /*	  All Rights Reserved  	*/
307c478bd9Sstevel@tonic-gate 
317c478bd9Sstevel@tonic-gate 
32*965005c8Schin #pragma ident	"%Z%%M%	%I%	%E% SMI"
337c478bd9Sstevel@tonic-gate /*
347c478bd9Sstevel@tonic-gate  * UNIX shell
357c478bd9Sstevel@tonic-gate  */
367c478bd9Sstevel@tonic-gate 
377c478bd9Sstevel@tonic-gate #include	"defs.h"
387c478bd9Sstevel@tonic-gate #include	<sys/procset.h>
397c478bd9Sstevel@tonic-gate #include	<siginfo.h>
407c478bd9Sstevel@tonic-gate #include	<ucontext.h>
417c478bd9Sstevel@tonic-gate #include	<errno.h>
427c478bd9Sstevel@tonic-gate #include	<string.h>
437c478bd9Sstevel@tonic-gate 
447c478bd9Sstevel@tonic-gate static	void (*psig0_func)() = SIG_ERR;	/* previous signal handler for signal 0 */
457c478bd9Sstevel@tonic-gate static	char sigsegv_stack[SIGSTKSZ];
467c478bd9Sstevel@tonic-gate 
477c478bd9Sstevel@tonic-gate static void sigsegv(int sig, siginfo_t *sip, ucontext_t *uap);
487c478bd9Sstevel@tonic-gate static void fault();
497c478bd9Sstevel@tonic-gate static BOOL sleeping = 0;
507c478bd9Sstevel@tonic-gate static unsigned char *trapcom[MAXTRAP]; /* array of actions, one per signal */
517c478bd9Sstevel@tonic-gate static BOOL trapflg[MAXTRAP] =
527c478bd9Sstevel@tonic-gate {
537c478bd9Sstevel@tonic-gate 	0,
547c478bd9Sstevel@tonic-gate 	0,	/* hangup */
557c478bd9Sstevel@tonic-gate 	0,	/* interrupt */
567c478bd9Sstevel@tonic-gate 	0,	/* quit */
577c478bd9Sstevel@tonic-gate 	0,	/* illegal instr */
587c478bd9Sstevel@tonic-gate 	0,	/* trace trap */
597c478bd9Sstevel@tonic-gate 	0,	/* IOT */
607c478bd9Sstevel@tonic-gate 	0,	/* EMT */
617c478bd9Sstevel@tonic-gate 	0,	/* float pt. exp */
627c478bd9Sstevel@tonic-gate 	0,	/* kill */
637c478bd9Sstevel@tonic-gate 	0, 	/* bus error */
647c478bd9Sstevel@tonic-gate 	0,	/* memory faults */
657c478bd9Sstevel@tonic-gate 	0,	/* bad sys call */
667c478bd9Sstevel@tonic-gate 	0,	/* bad pipe call */
677c478bd9Sstevel@tonic-gate 	0,	/* alarm */
687c478bd9Sstevel@tonic-gate 	0, 	/* software termination */
697c478bd9Sstevel@tonic-gate 	0,	/* unassigned */
707c478bd9Sstevel@tonic-gate 	0,	/* unassigned */
717c478bd9Sstevel@tonic-gate 	0,	/* death of child */
727c478bd9Sstevel@tonic-gate 	0,	/* power fail */
737c478bd9Sstevel@tonic-gate 	0,	/* window size change */
747c478bd9Sstevel@tonic-gate 	0,	/* urgent IO condition */
757c478bd9Sstevel@tonic-gate 	0,	/* pollable event occured */
767c478bd9Sstevel@tonic-gate 	0,	/* stopped by signal */
777c478bd9Sstevel@tonic-gate 	0,	/* stopped by user */
787c478bd9Sstevel@tonic-gate 	0,	/* continued */
797c478bd9Sstevel@tonic-gate 	0,	/* stopped by tty input */
807c478bd9Sstevel@tonic-gate 	0,	/* stopped by tty output */
817c478bd9Sstevel@tonic-gate 	0,	/* virtual timer expired */
827c478bd9Sstevel@tonic-gate 	0,	/* profiling timer expired */
837c478bd9Sstevel@tonic-gate 	0,	/* exceeded cpu limit */
847c478bd9Sstevel@tonic-gate 	0,	/* exceeded file size limit */
857c478bd9Sstevel@tonic-gate 	0, 	/* process's lwps are blocked */
867c478bd9Sstevel@tonic-gate 	0,	/* special signal used by thread library */
877c478bd9Sstevel@tonic-gate 	0, 	/* check point freeze */
887c478bd9Sstevel@tonic-gate 	0,	/* check point thaw */
897c478bd9Sstevel@tonic-gate };
907c478bd9Sstevel@tonic-gate 
917c478bd9Sstevel@tonic-gate static void (*(
927c478bd9Sstevel@tonic-gate sigval[MAXTRAP]))() =
937c478bd9Sstevel@tonic-gate {
947c478bd9Sstevel@tonic-gate 	0,
957c478bd9Sstevel@tonic-gate 	done, 	/* hangup */
967c478bd9Sstevel@tonic-gate 	fault,	/* interrupt */
977c478bd9Sstevel@tonic-gate 	fault,	/* quit */
987c478bd9Sstevel@tonic-gate 	done,	/* illegal instr */
997c478bd9Sstevel@tonic-gate 	done,	/* trace trap */
1007c478bd9Sstevel@tonic-gate 	done,	/* IOT */
1017c478bd9Sstevel@tonic-gate 	done,	/* EMT */
1027c478bd9Sstevel@tonic-gate 	done,	/* floating pt. exp */
1037c478bd9Sstevel@tonic-gate 	0,	/* kill */
1047c478bd9Sstevel@tonic-gate 	done, 	/* bus error */
1057c478bd9Sstevel@tonic-gate 	sigsegv,	/* memory faults */
1067c478bd9Sstevel@tonic-gate 	done, 	/* bad sys call */
1077c478bd9Sstevel@tonic-gate 	done,	/* bad pipe call */
1087c478bd9Sstevel@tonic-gate 	done,	/* alarm */
1097c478bd9Sstevel@tonic-gate 	fault,	/* software termination */
1107c478bd9Sstevel@tonic-gate 	done,	/* unassigned */
1117c478bd9Sstevel@tonic-gate 	done,	/* unassigned */
1127c478bd9Sstevel@tonic-gate 	0,	/* death of child */
1137c478bd9Sstevel@tonic-gate 	done,	/* power fail */
1147c478bd9Sstevel@tonic-gate 	0,	/* window size change */
1157c478bd9Sstevel@tonic-gate 	done,	/* urgent IO condition */
1167c478bd9Sstevel@tonic-gate 	done,	/* pollable event occured */
1177c478bd9Sstevel@tonic-gate 	0,	/* uncatchable stop */
1187c478bd9Sstevel@tonic-gate 	0,	/* foreground stop */
1197c478bd9Sstevel@tonic-gate 	0,	/* stopped process continued */
1207c478bd9Sstevel@tonic-gate 	0,	/* background tty read */
1217c478bd9Sstevel@tonic-gate 	0,	/* background tty write */
1227c478bd9Sstevel@tonic-gate 	done,	/* virtual timer expired */
1237c478bd9Sstevel@tonic-gate 	done,	/* profiling timer expired */
1247c478bd9Sstevel@tonic-gate 	done,	/* exceeded cpu limit */
1257c478bd9Sstevel@tonic-gate 	done,	/* exceeded file size limit */
1267c478bd9Sstevel@tonic-gate 	0, 	/* process's lwps are blocked */
1277c478bd9Sstevel@tonic-gate 	0,	/* special signal used by thread library */
1287c478bd9Sstevel@tonic-gate 	0, 	/* check point freeze */
1297c478bd9Sstevel@tonic-gate 	0,	/* check point thaw */
1307c478bd9Sstevel@tonic-gate };
1317c478bd9Sstevel@tonic-gate 
1327c478bd9Sstevel@tonic-gate static int
133*965005c8Schin ignoring(int i)
1347c478bd9Sstevel@tonic-gate {
1357c478bd9Sstevel@tonic-gate 	struct sigaction act;
1367c478bd9Sstevel@tonic-gate 	if (trapflg[i] & SIGIGN)
1377c478bd9Sstevel@tonic-gate 		return (1);
1387c478bd9Sstevel@tonic-gate 	sigaction(i, 0, &act);
1397c478bd9Sstevel@tonic-gate 	if (act.sa_handler == SIG_IGN) {
1407c478bd9Sstevel@tonic-gate 		trapflg[i] |= SIGIGN;
1417c478bd9Sstevel@tonic-gate 		return (1);
1427c478bd9Sstevel@tonic-gate 	}
1437c478bd9Sstevel@tonic-gate 	return (0);
1447c478bd9Sstevel@tonic-gate }
1457c478bd9Sstevel@tonic-gate 
1467c478bd9Sstevel@tonic-gate static void
1477c478bd9Sstevel@tonic-gate clrsig(i)
1487c478bd9Sstevel@tonic-gate int	i;
1497c478bd9Sstevel@tonic-gate {
1507c478bd9Sstevel@tonic-gate 	if (trapcom[i] != 0) {
1517c478bd9Sstevel@tonic-gate 		free(trapcom[i]);
1527c478bd9Sstevel@tonic-gate 		trapcom[i] = 0;
1537c478bd9Sstevel@tonic-gate 	}
1547c478bd9Sstevel@tonic-gate 
1557c478bd9Sstevel@tonic-gate 
1567c478bd9Sstevel@tonic-gate 	if (trapflg[i] & SIGMOD) {
1577c478bd9Sstevel@tonic-gate 		/*
1587c478bd9Sstevel@tonic-gate 		 * If the signal has been set to SIGIGN and we are now
1597c478bd9Sstevel@tonic-gate 		 * clearing the disposition of the signal (restoring it
1607c478bd9Sstevel@tonic-gate 		 * back to its default value) then we need to clear this
1617c478bd9Sstevel@tonic-gate 		 * bit as well
1627c478bd9Sstevel@tonic-gate 		 *
1637c478bd9Sstevel@tonic-gate 		 */
1647c478bd9Sstevel@tonic-gate 		if (trapflg[i] & SIGIGN)
1657c478bd9Sstevel@tonic-gate 			trapflg[i] &= ~SIGIGN;
1667c478bd9Sstevel@tonic-gate 
1677c478bd9Sstevel@tonic-gate 		trapflg[i] &= ~SIGMOD;
1687c478bd9Sstevel@tonic-gate 		handle(i, sigval[i]);
1697c478bd9Sstevel@tonic-gate 	}
1707c478bd9Sstevel@tonic-gate }
1717c478bd9Sstevel@tonic-gate 
1727c478bd9Sstevel@tonic-gate void
1737c478bd9Sstevel@tonic-gate done(sig)
1747c478bd9Sstevel@tonic-gate {
175*965005c8Schin 	unsigned char	*t;
1767c478bd9Sstevel@tonic-gate 	int	savxit;
1777c478bd9Sstevel@tonic-gate 
1787c478bd9Sstevel@tonic-gate 	if (t = trapcom[0])
1797c478bd9Sstevel@tonic-gate 	{
1807c478bd9Sstevel@tonic-gate 		trapcom[0] = 0;
1817c478bd9Sstevel@tonic-gate 		/* Save exit value so trap handler will not change its val */
1827c478bd9Sstevel@tonic-gate 		savxit = exitval;
1837c478bd9Sstevel@tonic-gate 		execexp(t, 0);
1847c478bd9Sstevel@tonic-gate 		exitval = savxit;		/* Restore exit value */
1857c478bd9Sstevel@tonic-gate 		free(t);
1867c478bd9Sstevel@tonic-gate 	}
1877c478bd9Sstevel@tonic-gate 	else
1887c478bd9Sstevel@tonic-gate 		chktrap();
1897c478bd9Sstevel@tonic-gate 
1907c478bd9Sstevel@tonic-gate 	rmtemp(0);
1917c478bd9Sstevel@tonic-gate 	rmfunctmp();
1927c478bd9Sstevel@tonic-gate 
1937c478bd9Sstevel@tonic-gate #ifdef ACCT
1947c478bd9Sstevel@tonic-gate 	doacct();
1957c478bd9Sstevel@tonic-gate #endif
1967c478bd9Sstevel@tonic-gate 	if (flags & subsh) {
1977c478bd9Sstevel@tonic-gate 		/* in a subshell, need to wait on foreground job */
1987c478bd9Sstevel@tonic-gate 		collect_fg_job();
1997c478bd9Sstevel@tonic-gate 	}
2007c478bd9Sstevel@tonic-gate 
2017c478bd9Sstevel@tonic-gate 	(void) endjobs(0);
2027c478bd9Sstevel@tonic-gate 	if (sig) {
2037c478bd9Sstevel@tonic-gate 		sigset_t set;
2047c478bd9Sstevel@tonic-gate 		sigemptyset(&set);
2057c478bd9Sstevel@tonic-gate 		sigaddset(&set, sig);
2067c478bd9Sstevel@tonic-gate 		sigprocmask(SIG_UNBLOCK, &set, 0);
2077c478bd9Sstevel@tonic-gate 		handle(sig, SIG_DFL);
2087c478bd9Sstevel@tonic-gate 		kill(mypid, sig);
2097c478bd9Sstevel@tonic-gate 	}
2107c478bd9Sstevel@tonic-gate 	exit(exitval);
2117c478bd9Sstevel@tonic-gate }
2127c478bd9Sstevel@tonic-gate 
2137c478bd9Sstevel@tonic-gate static void
214*965005c8Schin fault(int sig)
2157c478bd9Sstevel@tonic-gate {
216*965005c8Schin 	int flag;
2177c478bd9Sstevel@tonic-gate 
2187c478bd9Sstevel@tonic-gate 	switch (sig) {
2197c478bd9Sstevel@tonic-gate 		case SIGALRM:
2207c478bd9Sstevel@tonic-gate 			if (sleeping)
2217c478bd9Sstevel@tonic-gate 				return;
2227c478bd9Sstevel@tonic-gate 			break;
2237c478bd9Sstevel@tonic-gate 	}
2247c478bd9Sstevel@tonic-gate 
2257c478bd9Sstevel@tonic-gate 	if (trapcom[sig])
2267c478bd9Sstevel@tonic-gate 		flag = TRAPSET;
2277c478bd9Sstevel@tonic-gate 	else if (flags & subsh)
2287c478bd9Sstevel@tonic-gate 		done(sig);
2297c478bd9Sstevel@tonic-gate 	else
2307c478bd9Sstevel@tonic-gate 		flag = SIGSET;
2317c478bd9Sstevel@tonic-gate 
2327c478bd9Sstevel@tonic-gate 	trapnote |= flag;
2337c478bd9Sstevel@tonic-gate 	trapflg[sig] |= flag;
2347c478bd9Sstevel@tonic-gate }
2357c478bd9Sstevel@tonic-gate 
2367c478bd9Sstevel@tonic-gate int
2377c478bd9Sstevel@tonic-gate handle(sig, func)
2387c478bd9Sstevel@tonic-gate 	int sig;
2397c478bd9Sstevel@tonic-gate 	void (*func)();
2407c478bd9Sstevel@tonic-gate {
2417c478bd9Sstevel@tonic-gate 	int	ret;
2427c478bd9Sstevel@tonic-gate 	struct sigaction act, oact;
2437c478bd9Sstevel@tonic-gate 
2447c478bd9Sstevel@tonic-gate 	if (func == SIG_IGN && (trapflg[sig] & SIGIGN))
2457c478bd9Sstevel@tonic-gate 		return (0);
2467c478bd9Sstevel@tonic-gate 
2477c478bd9Sstevel@tonic-gate 	/*
2487c478bd9Sstevel@tonic-gate 	 * Ensure that sigaction is only called with valid signal numbers,
2497c478bd9Sstevel@tonic-gate 	 * we can get random values back for oact.sa_handler if the signal
2507c478bd9Sstevel@tonic-gate 	 * number is invalid
2517c478bd9Sstevel@tonic-gate 	 *
2527c478bd9Sstevel@tonic-gate 	 */
2537c478bd9Sstevel@tonic-gate 	if (sig > MINTRAP && sig < MAXTRAP) {
2547c478bd9Sstevel@tonic-gate 		sigemptyset(&act.sa_mask);
2557c478bd9Sstevel@tonic-gate 		act.sa_flags = (sig == SIGSEGV) ? (SA_ONSTACK | SA_SIGINFO) : 0;
2567c478bd9Sstevel@tonic-gate 		act.sa_handler = func;
2577c478bd9Sstevel@tonic-gate 		sigaction(sig, &act, &oact);
2587c478bd9Sstevel@tonic-gate 	}
2597c478bd9Sstevel@tonic-gate 
2607c478bd9Sstevel@tonic-gate 	if (func == SIG_IGN)
2617c478bd9Sstevel@tonic-gate 		trapflg[sig] |= SIGIGN;
2627c478bd9Sstevel@tonic-gate 
2637c478bd9Sstevel@tonic-gate 	/*
2647c478bd9Sstevel@tonic-gate 	 * Special case for signal zero, we can not obtain the previos
2657c478bd9Sstevel@tonic-gate 	 * action by calling sigaction, instead we save it in the variable
2667c478bd9Sstevel@tonic-gate 	 * psig0_func, so we can test it next time through this code
2677c478bd9Sstevel@tonic-gate 	 *
2687c478bd9Sstevel@tonic-gate 	 */
2697c478bd9Sstevel@tonic-gate 	if (sig == 0) {
2707c478bd9Sstevel@tonic-gate 		ret = (psig0_func != func);
2717c478bd9Sstevel@tonic-gate 		psig0_func = func;
2727c478bd9Sstevel@tonic-gate 	} else {
2737c478bd9Sstevel@tonic-gate 		ret = (func != oact.sa_handler);
2747c478bd9Sstevel@tonic-gate 	}
2757c478bd9Sstevel@tonic-gate 
2767c478bd9Sstevel@tonic-gate 	return (ret);
2777c478bd9Sstevel@tonic-gate }
2787c478bd9Sstevel@tonic-gate 
2797c478bd9Sstevel@tonic-gate void
2807c478bd9Sstevel@tonic-gate stdsigs()
2817c478bd9Sstevel@tonic-gate {
282*965005c8Schin 	int	i;
2837c478bd9Sstevel@tonic-gate 	stack_t	ss;
2847c478bd9Sstevel@tonic-gate 	int	err = 0;
2857c478bd9Sstevel@tonic-gate 	int rtmin = (int)SIGRTMIN;
2867c478bd9Sstevel@tonic-gate 	int rtmax = (int)SIGRTMAX;
2877c478bd9Sstevel@tonic-gate 
2887c478bd9Sstevel@tonic-gate 	ss.ss_size = SIGSTKSZ;
2897c478bd9Sstevel@tonic-gate 	ss.ss_sp = sigsegv_stack;
2907c478bd9Sstevel@tonic-gate 	ss.ss_flags = 0;
2917c478bd9Sstevel@tonic-gate 	errno = 0;
2927c478bd9Sstevel@tonic-gate 	if (sigaltstack(&ss, (stack_t *)NULL) == -1) {
2937c478bd9Sstevel@tonic-gate 		err = errno;
2947c478bd9Sstevel@tonic-gate 		failure("sigaltstack(2) failed with", strerror(err));
2957c478bd9Sstevel@tonic-gate 	}
2967c478bd9Sstevel@tonic-gate 
2977c478bd9Sstevel@tonic-gate 	for (i = 1; i < MAXTRAP; i++) {
2987c478bd9Sstevel@tonic-gate 		if (i == rtmin) {
2997c478bd9Sstevel@tonic-gate 			i = rtmax;
3007c478bd9Sstevel@tonic-gate 			continue;
3017c478bd9Sstevel@tonic-gate 		}
3027c478bd9Sstevel@tonic-gate 		if (sigval[i] == 0)
3037c478bd9Sstevel@tonic-gate 			continue;
3047c478bd9Sstevel@tonic-gate 		if (i != SIGSEGV && ignoring(i))
3057c478bd9Sstevel@tonic-gate 			continue;
3067c478bd9Sstevel@tonic-gate 		handle(i, sigval[i]);
3077c478bd9Sstevel@tonic-gate 	}
3087c478bd9Sstevel@tonic-gate 
3097c478bd9Sstevel@tonic-gate 	/*
3107c478bd9Sstevel@tonic-gate 	 * handle all the realtime signals
3117c478bd9Sstevel@tonic-gate 	 *
3127c478bd9Sstevel@tonic-gate 	 */
3137c478bd9Sstevel@tonic-gate 	for (i = rtmin; i <= rtmax; i++) {
3147c478bd9Sstevel@tonic-gate 		handle(i, done);
3157c478bd9Sstevel@tonic-gate 	}
3167c478bd9Sstevel@tonic-gate }
3177c478bd9Sstevel@tonic-gate 
3187c478bd9Sstevel@tonic-gate void
3197c478bd9Sstevel@tonic-gate oldsigs()
3207c478bd9Sstevel@tonic-gate {
321*965005c8Schin 	int	i;
322*965005c8Schin 	unsigned char	*t;
3237c478bd9Sstevel@tonic-gate 
3247c478bd9Sstevel@tonic-gate 	i = MAXTRAP;
3257c478bd9Sstevel@tonic-gate 	while (i--)
3267c478bd9Sstevel@tonic-gate 	{
3277c478bd9Sstevel@tonic-gate 		t = trapcom[i];
3287c478bd9Sstevel@tonic-gate 		if (t == 0 || *t)
3297c478bd9Sstevel@tonic-gate 			clrsig(i);
3307c478bd9Sstevel@tonic-gate 		trapflg[i] = 0;
3317c478bd9Sstevel@tonic-gate 	}
3327c478bd9Sstevel@tonic-gate 	trapnote = 0;
3337c478bd9Sstevel@tonic-gate }
3347c478bd9Sstevel@tonic-gate 
3357c478bd9Sstevel@tonic-gate /*
3367c478bd9Sstevel@tonic-gate  * check for traps
3377c478bd9Sstevel@tonic-gate  */
3387c478bd9Sstevel@tonic-gate 
3397c478bd9Sstevel@tonic-gate void
3407c478bd9Sstevel@tonic-gate chktrap()
3417c478bd9Sstevel@tonic-gate {
342*965005c8Schin 	int	i = MAXTRAP;
343*965005c8Schin 	unsigned char	*t;
3447c478bd9Sstevel@tonic-gate 
3457c478bd9Sstevel@tonic-gate 	trapnote &= ~TRAPSET;
3467c478bd9Sstevel@tonic-gate 	while (--i)
3477c478bd9Sstevel@tonic-gate 	{
3487c478bd9Sstevel@tonic-gate 		if (trapflg[i] & TRAPSET)
3497c478bd9Sstevel@tonic-gate 		{
3507c478bd9Sstevel@tonic-gate 			trapflg[i] &= ~TRAPSET;
3517c478bd9Sstevel@tonic-gate 			if (t = trapcom[i])
3527c478bd9Sstevel@tonic-gate 			{
3537c478bd9Sstevel@tonic-gate 				int	savxit = exitval;
3547c478bd9Sstevel@tonic-gate 				execexp(t, 0);
3557c478bd9Sstevel@tonic-gate 				exitval = savxit;
3567c478bd9Sstevel@tonic-gate 				exitset();
3577c478bd9Sstevel@tonic-gate 			}
3587c478bd9Sstevel@tonic-gate 		}
3597c478bd9Sstevel@tonic-gate 	}
3607c478bd9Sstevel@tonic-gate }
3617c478bd9Sstevel@tonic-gate 
362*965005c8Schin void
363*965005c8Schin systrap(int argc, char **argv)
3647c478bd9Sstevel@tonic-gate {
3657c478bd9Sstevel@tonic-gate 	int sig;
3667c478bd9Sstevel@tonic-gate 
3677c478bd9Sstevel@tonic-gate 	if (argc == 1) {
3687c478bd9Sstevel@tonic-gate 		/*
3697c478bd9Sstevel@tonic-gate 		 * print out the current action associated with each signal
3707c478bd9Sstevel@tonic-gate 		 * handled by the shell
3717c478bd9Sstevel@tonic-gate 		 *
3727c478bd9Sstevel@tonic-gate 		 */
3737c478bd9Sstevel@tonic-gate 		for (sig = 0; sig < MAXTRAP; sig++) {
3747c478bd9Sstevel@tonic-gate 			if (trapcom[sig]) {
3757c478bd9Sstevel@tonic-gate 				prn_buff(sig);
3767c478bd9Sstevel@tonic-gate 				prs_buff(colon);
3777c478bd9Sstevel@tonic-gate 				prs_buff(trapcom[sig]);
3787c478bd9Sstevel@tonic-gate 				prc_buff(NL);
3797c478bd9Sstevel@tonic-gate 			}
3807c478bd9Sstevel@tonic-gate 		}
3817c478bd9Sstevel@tonic-gate 	} else {
3827c478bd9Sstevel@tonic-gate 		/*
3837c478bd9Sstevel@tonic-gate 		 * set the action for the list of signals
3847c478bd9Sstevel@tonic-gate 		 *
3857c478bd9Sstevel@tonic-gate 		 */
3867c478bd9Sstevel@tonic-gate 		char *cmd = *argv, *a1 = *(argv+1);
3877c478bd9Sstevel@tonic-gate 		BOOL noa1;
3887c478bd9Sstevel@tonic-gate 		noa1 = (str2sig(a1, &sig) == 0);
3897c478bd9Sstevel@tonic-gate 		if (noa1 == 0)
3907c478bd9Sstevel@tonic-gate 			++argv;
3917c478bd9Sstevel@tonic-gate 		while (*++argv) {
3927c478bd9Sstevel@tonic-gate 			if (str2sig(*argv, &sig) < 0 ||
3937c478bd9Sstevel@tonic-gate 			    sig >= MAXTRAP || sig < MINTRAP ||
3947c478bd9Sstevel@tonic-gate 			    sig == SIGSEGV) {
3957c478bd9Sstevel@tonic-gate 				failure(cmd, badtrap);
3967c478bd9Sstevel@tonic-gate 			} else if (noa1) {
3977c478bd9Sstevel@tonic-gate 				/*
3987c478bd9Sstevel@tonic-gate 				 * no action specifed so reset the siganl
3997c478bd9Sstevel@tonic-gate 				 * to its default disposition
4007c478bd9Sstevel@tonic-gate 				 *
4017c478bd9Sstevel@tonic-gate 				 */
4027c478bd9Sstevel@tonic-gate 				clrsig(sig);
4037c478bd9Sstevel@tonic-gate 			} else if (*a1) {
4047c478bd9Sstevel@tonic-gate 				/*
4057c478bd9Sstevel@tonic-gate 				 * set the action associated with the signal
4067c478bd9Sstevel@tonic-gate 				 * to a1
4077c478bd9Sstevel@tonic-gate 				 *
4087c478bd9Sstevel@tonic-gate 				 */
4097c478bd9Sstevel@tonic-gate 				if (trapflg[sig] & SIGMOD || sig == 0 ||
4107c478bd9Sstevel@tonic-gate 				    !ignoring(sig)) {
4117c478bd9Sstevel@tonic-gate 					handle(sig, fault);
4127c478bd9Sstevel@tonic-gate 					trapflg[sig] |= SIGMOD;
4137c478bd9Sstevel@tonic-gate 					replace(&trapcom[sig], a1);
4147c478bd9Sstevel@tonic-gate 				}
4157c478bd9Sstevel@tonic-gate 			} else if (handle(sig, SIG_IGN)) {
4167c478bd9Sstevel@tonic-gate 				/*
4177c478bd9Sstevel@tonic-gate 				 * set the action associated with the signal
4187c478bd9Sstevel@tonic-gate 				 * to SIG_IGN
4197c478bd9Sstevel@tonic-gate 				 *
4207c478bd9Sstevel@tonic-gate 				 */
4217c478bd9Sstevel@tonic-gate 				trapflg[sig] |= SIGMOD;
4227c478bd9Sstevel@tonic-gate 				replace(&trapcom[sig], a1);
4237c478bd9Sstevel@tonic-gate 			}
4247c478bd9Sstevel@tonic-gate 		}
4257c478bd9Sstevel@tonic-gate 	}
4267c478bd9Sstevel@tonic-gate }
4277c478bd9Sstevel@tonic-gate 
428*965005c8Schin void
429*965005c8Schin sh_sleep(unsigned int ticks)
4307c478bd9Sstevel@tonic-gate {
4317c478bd9Sstevel@tonic-gate 	sigset_t set, oset;
4327c478bd9Sstevel@tonic-gate 	struct sigaction act, oact;
4337c478bd9Sstevel@tonic-gate 
4347c478bd9Sstevel@tonic-gate 
4357c478bd9Sstevel@tonic-gate 	/*
4367c478bd9Sstevel@tonic-gate 	 * add SIGALRM to mask
4377c478bd9Sstevel@tonic-gate 	 */
4387c478bd9Sstevel@tonic-gate 
4397c478bd9Sstevel@tonic-gate 	sigemptyset(&set);
4407c478bd9Sstevel@tonic-gate 	sigaddset(&set, SIGALRM);
4417c478bd9Sstevel@tonic-gate 	sigprocmask(SIG_BLOCK, &set, &oset);
4427c478bd9Sstevel@tonic-gate 
4437c478bd9Sstevel@tonic-gate 	/*
4447c478bd9Sstevel@tonic-gate 	 * catch SIGALRM
4457c478bd9Sstevel@tonic-gate 	 */
4467c478bd9Sstevel@tonic-gate 
4477c478bd9Sstevel@tonic-gate 	sigemptyset(&act.sa_mask);
4487c478bd9Sstevel@tonic-gate 	act.sa_flags = 0;
4497c478bd9Sstevel@tonic-gate 	act.sa_handler = fault;
4507c478bd9Sstevel@tonic-gate 	sigaction(SIGALRM, &act, &oact);
4517c478bd9Sstevel@tonic-gate 
4527c478bd9Sstevel@tonic-gate 	/*
4537c478bd9Sstevel@tonic-gate 	 * start alarm and wait for signal
4547c478bd9Sstevel@tonic-gate 	 */
4557c478bd9Sstevel@tonic-gate 
4567c478bd9Sstevel@tonic-gate 	alarm(ticks);
4577c478bd9Sstevel@tonic-gate 	sleeping = 1;
4587c478bd9Sstevel@tonic-gate 	sigsuspend(&oset);
4597c478bd9Sstevel@tonic-gate 	sleeping = 0;
4607c478bd9Sstevel@tonic-gate 
4617c478bd9Sstevel@tonic-gate 	/*
4627c478bd9Sstevel@tonic-gate 	 * reset alarm, catcher and mask
4637c478bd9Sstevel@tonic-gate 	 */
4647c478bd9Sstevel@tonic-gate 
4657c478bd9Sstevel@tonic-gate 	alarm(0);
4667c478bd9Sstevel@tonic-gate 	sigaction(SIGALRM, &oact, NULL);
4677c478bd9Sstevel@tonic-gate 	sigprocmask(SIG_SETMASK, &oset, 0);
4687c478bd9Sstevel@tonic-gate 
4697c478bd9Sstevel@tonic-gate }
4707c478bd9Sstevel@tonic-gate 
4717c478bd9Sstevel@tonic-gate void
4727c478bd9Sstevel@tonic-gate sigsegv(int sig, siginfo_t *sip, ucontext_t *uap)
4737c478bd9Sstevel@tonic-gate {
4747c478bd9Sstevel@tonic-gate 	if (sip == (siginfo_t *)NULL) {
4757c478bd9Sstevel@tonic-gate 		/*
4767c478bd9Sstevel@tonic-gate 		 * This should never happen, but if it does this is all we
4777c478bd9Sstevel@tonic-gate 		 * can do. It can only happen if sigaction(2) for SIGSEGV
4787c478bd9Sstevel@tonic-gate 		 * has been called without SA_SIGINFO being set.
4797c478bd9Sstevel@tonic-gate 		 *
4807c478bd9Sstevel@tonic-gate 		 */
4817c478bd9Sstevel@tonic-gate 
4827c478bd9Sstevel@tonic-gate 		exit(ERROR);
4837c478bd9Sstevel@tonic-gate 	} else {
4847c478bd9Sstevel@tonic-gate 		if (sip->si_code <= 0) {
4857c478bd9Sstevel@tonic-gate 			/*
4867c478bd9Sstevel@tonic-gate 			 * If we are here then SIGSEGV must have been sent to
4877c478bd9Sstevel@tonic-gate 			 * us from a user process NOT as a result of an
4887c478bd9Sstevel@tonic-gate 			 * internal error within the shell eg
4897c478bd9Sstevel@tonic-gate 			 * kill -SEGV $$
4907c478bd9Sstevel@tonic-gate 			 * will bring us here. So do the normal thing.
4917c478bd9Sstevel@tonic-gate 			 *
4927c478bd9Sstevel@tonic-gate 			 */
4937c478bd9Sstevel@tonic-gate 			fault(sig);
4947c478bd9Sstevel@tonic-gate 		} else {
4957c478bd9Sstevel@tonic-gate 			/*
4967c478bd9Sstevel@tonic-gate 			 * If we are here then there must have been an internal
4977c478bd9Sstevel@tonic-gate 			 * error within the shell to generate SIGSEGV eg
4987c478bd9Sstevel@tonic-gate 			 * the stack is full and we cannot call any more
4997c478bd9Sstevel@tonic-gate 			 * functions (Remeber this signal handler is running
5007c478bd9Sstevel@tonic-gate 			 * on an alternate stack). So we just exit cleanly
5017c478bd9Sstevel@tonic-gate 			 * with an error status (no core file).
5027c478bd9Sstevel@tonic-gate 			 */
5037c478bd9Sstevel@tonic-gate 			exit(ERROR);
5047c478bd9Sstevel@tonic-gate 		}
5057c478bd9Sstevel@tonic-gate 	}
5067c478bd9Sstevel@tonic-gate }
507