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