1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * A copy of the CDDL is also available via the Internet at
11  * http://www.opensource.org/licenses/cddl1.txt
12  * See the License for the specific language governing permissions
13  * and limitations under the License.
14  *
15  * When distributing Covered Code, include this CDDL HEADER in each
16  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
17  * If applicable, add the following below this CDDL HEADER, with the
18  * fields enclosed by brackets "[]" replaced with your own identifying
19  * information: Portions Copyright [yyyy] [name of copyright owner]
20  *
21  * CDDL HEADER END
22  */
23 
24 /*
25  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
26  * Use is subject to license terms.
27  */
28 
29 /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
30 /*	  All Rights Reserved  	*/
31 
32 #if defined(sun)
33 #pragma ident	"@(#)fault.c	1.29	06/06/16 SMI"
34 #endif
35 
36 #include "defs.h"
37 
38 /*
39  * Copyright 2008-2021 J. Schilling
40  *
41  * @(#)fault.c	1.53 21/08/13 2008-2021 J. Schilling
42  */
43 #ifndef lint
44 static	UConst char sccsid[] =
45 	"@(#)fault.c	1.53 21/08/13 2008-2021 J. Schilling";
46 #endif
47 
48 /*
49  * UNIX shell
50  */
51 #ifdef	SCHILY_INCLUDES
52 #ifdef	HAVE_SYS_PROCSET_H
53 #include	<sys/procset.h>
54 #endif
55 #ifdef	HAVE_SIGINFO_H
56 #include	<siginfo.h>
57 #endif
58 #ifndef	HAVE_SIGINFO_T
59 #define	siginfo_t char
60 #endif
61 #ifndef	HAVE_STACK_T
62 #define	stack_t char
63 #endif
64 #ifndef	SIGSTKSZ
65 #define	SIGSTKSZ	8192
66 #define	HAVE_SIGSTKSZ_CONST	1
67 #endif
68 #ifndef	SA_SIGINFO
69 #define	SA_SIGINFO	0
70 #endif
71 #ifndef	SA_ONSTACK
72 #define	SA_ONSTACK	0
73 #endif
74 #ifdef	HAVE_UCONTEXT_H
75 #include	<ucontext.h>
76 #else
77 #define	ucontext_t char
78 #endif
79 #include	<schily/errno.h>
80 #include	<schily/string.h>
81 #else
82 #include	<sys/procset.h>
83 #include	<siginfo.h>
84 #include	<ucontext.h>
85 #include	<errno.h>
86 #include	<string.h>
87 #endif
88 
89 /*
90  * intrptr is a pointer to an integer that is incremented whenever
91  * a SIGINT is received and handled. This is used to inform additional
92  * "builtin" commands about an interrupt, e.g. the builtins from the
93  * Comand History Editor.
94  */
95 	int	*intrptr;
96 
97 /*
98  * Whether to use _exit() because we did call vfork()
99  */
100 	int	exflag;
101 
102 /*
103  * previous signal handler for signal 0 and ERR
104  */
105 static	void (*psig0_func) __PR((int)) = SIG_ERR;
106 #ifdef	DO_ERR_TRAP
107 static	void (*psigerr_func) __PR((int)) = SIG_ERR;
108 #endif
109 
110 #if defined(HAVE_STACK_T) && defined(HAVE_SIGALTSTACK)
111 #ifdef	HAVE_SIGSTKSZ_CONST
112 static	char sigsegv_stack[SIGSTKSZ];
113 #endif
114 #endif
115 
116 static int	ignoring	__PR((int i));
117 static void	clrsig		__PR((int i, int dofree));
118 	void	done		__PR((int sig));
119 	void	fault		__PR((int sig));
120 	int	handle		__PR((int sig, sigtype func));
121 	void	stdsigs		__PR((void));
122 	void	oldsigs		__PR((int dofree));
123 #ifdef	HAVE_VFORK
124 	void	restoresigs	__PR((void));
125 #endif
126 	void	chktrap		__PR((void));
127 static	int	str2trap	__PR((char *s, int *sig));
128 #ifdef	DO_POSIX_TRAP
129 static	int	trap2str	__PR((int sig, char *buf));
130 #endif
131 static	void	prtrap		__PR((int sig));
132 	void	systrap		__PR((int argc, char **argv));
133 	void	sh_sleep	__PR((unsigned int ticks));
134 static void	sigsegv		__PR((int sig, siginfo_t *sip,
135 						ucontext_t *uap));
136 static void	set_sigval	__PR((int sig, void (*fun)(int)));
137 	void	init_sigval	__PR((void));
138 
139 static BOOL	sleeping = 0;
140 	unsigned char *trapcom[MAXTRAP]; /* array of actions, one per signal */
141 static BOOL	trapflg[MAXTRAP] =
142 {
143 	0,
144 	0,	/* hangup */
145 	0,	/* interrupt */
146 	0,	/* quit */
147 #ifdef	__never__ /* For portability, we cannot asume > 3 signals */
148 	0,	/* illegal instr */
149 	0,	/* trace trap */
150 	0,	/* IOT */
151 	0,	/* EMT */
152 	0,	/* float pt. exp */
153 	0,	/* kill */
154 	0,	/* bus error */
155 	0,	/* memory faults */
156 	0,	/* bad sys call */
157 	0,	/* bad pipe call */
158 	0,	/* alarm */
159 	0,	/* software termination */
160 	0,	/* unassigned */
161 	0,	/* unassigned */
162 	0,	/* death of child */
163 	0,	/* power fail */
164 	0,	/* window size change */
165 	0,	/* urgent IO condition */
166 	0,	/* pollable event occured */
167 	0,	/* stopped by signal */
168 	0,	/* stopped by user */
169 	0,	/* continued */
170 	0,	/* stopped by tty input */
171 	0,	/* stopped by tty output */
172 	0,	/* virtual timer expired */
173 	0,	/* profiling timer expired */
174 	0,	/* exceeded cpu limit */
175 	0,	/* exceeded file size limit */
176 	0,	/* process's lwps are blocked */
177 	0,	/* special signal used by thread library */
178 	0,	/* check point freeze */
179 	0,	/* check point thaw */
180 #endif
181 };
182 
183 /*
184  * NOTE: Signal numbers other then 1, 2, 3, 6, 9, 14, and 15 are not portable.
185  *	 We thus cannot use a pre-initialized table for signal numbers > 3.
186  */
187 static void (*(
188 sigval[MAXTRAP])) __PR((int)) =
189 {
190 	0,
191 	done,	/* hangup */
192 	fault,	/* interrupt */
193 	fault,	/* quit */
194 #ifdef	__never__ /* For portability, we cannot asume > 3 signals */
195 	done,	/* illegal instr */
196 	done,	/* trace trap */
197 	done,	/* IOT / ABRT */
198 	done,	/* EMT */
199 	done,	/* floating pt. exp */
200 	0,	/* kill */
201 	done,	/* bus error */
202 	sigsegv,	/* memory faults */
203 	done,	/* bad sys call */
204 	done,	/* bad pipe call */
205 	done,	/* alarm */
206 	fault,	/* software termination */
207 	done,	/* unassigned */
208 	done,	/* unassigned */
209 	0,	/* death of child */
210 	done,	/* power fail */
211 	0,	/* window size change */
212 	done,	/* urgent IO condition */
213 	done,	/* pollable event occured */
214 	0,	/* uncatchable stop */
215 	0,	/* foreground stop */
216 	0,	/* stopped process continued */
217 	0,	/* background tty read */
218 	0,	/* background tty write */
219 	done,	/* virtual timer expired */
220 	done,	/* profiling timer expired */
221 	done,	/* exceeded cpu limit */
222 	done,	/* exceeded file size limit */
223 	0,	/* process's lwps are blocked */
224 	0,	/* special signal used by thread library */
225 	0,	/* check point freeze */
226 	0,	/* check point thaw */
227 #endif
228 };
229 
230 static int
ignoring(i)231 ignoring(i)
232 	int	i;
233 {
234 	struct sigaction act;
235 	if (trapflg[i] & SIGIGN)
236 		return (1);
237 	sigaction(i, 0, &act);
238 	if (act.sa_handler == SIG_IGN) {
239 		trapflg[i] |= SIGIGN;
240 		return (1);
241 	}
242 	return (0);
243 }
244 
245 static void
clrsig(i,dofree)246 clrsig(i, dofree)
247 	int	i;
248 	int	dofree;
249 {
250 	if (dofree && trapcom[i] != 0) {
251 		free(trapcom[i]);
252 		trapcom[i] = 0;
253 	}
254 
255 
256 	if (trapflg[i] & SIGMOD) {
257 		/*
258 		 * If the signal has been set to SIGIGN and we are now
259 		 * clearing the disposition of the signal (restoring it
260 		 * back to its default value) then we need to clear this
261 		 * bit as well
262 		 *
263 		 */
264 		if (trapflg[i] & SIGIGN)
265 			trapflg[i] &= ~SIGIGN;
266 
267 		trapflg[i] &= ~SIGMOD;
268 		handle(i, sigval[i]);
269 	}
270 }
271 
272 void
done(sig)273 done(sig)
274 	int	sig;
275 {
276 	unsigned char	*t;
277 	int	savxit;
278 	struct excode savex;
279 	struct excode savrex;
280 
281 	if ((t = trapcom[0]) != NULL && (trapflg[0] & SIGCLR) == 0) {
282 		trapcom[0] = 0;
283 		/* Save exit value so trap handler will not change its val */
284 		savxit = exitval;
285 		savex = ex;
286 		savrex = retex;
287 		retex.ex_signo = 0;
288 		execexp(t, (Intptr_t)0, 0);
289 		exitval = savxit;		/* Restore exit value */
290 		ex = savex;
291 		retex = savrex;
292 		free(t);
293 	} else {
294 		if (!(flags & errflg))		/* Do not call ERR 2 times */
295 			traprecurse++;
296 		chktrap();
297 	}
298 	if (xiotemp) {
299 		rmtemp(xiotemp);
300 		xiotemp = NULL;
301 	} else {
302 		rmtemp(0);
303 	}
304 	rmfunctmp(0);
305 
306 #ifdef ACCT
307 	doacct();
308 #endif
309 	if (flags & subsh) {
310 		/* in a subshell, need to wait on foreground job */
311 		collect_fg_job();
312 	}
313 
314 	(void) endjobs(0);
315 	if (sig) {
316 		sigset_t set;
317 
318 		/*
319 		 * If the signal is SIGHUP, then it should be delivered
320 		 * to the process group leader of the foreground job.
321 		 */
322 		if (sig == SIGHUP)
323 			hupforegnd();
324 
325 		sigemptyset(&set);
326 		sigaddset(&set, sig);
327 		sigprocmask(SIG_UNBLOCK, &set, 0);
328 		handle(sig, SIG_DFL);
329 		/*
330 		 * We cannot use mypid here as we may get a signal before we
331 		 * did set up mypid. Using mypid thus includes the chance to
332 		 * kill out parent instead of ourself.
333 		 */
334 		kill(getpid(), sig);
335 	}
336 	if (exflag)
337 		_exit(exitval);
338 	exit(exitval);
339 }
340 
341 void
fault(sig)342 fault(sig)
343 	int	sig;
344 {
345 	int flag = 0;
346 
347 	switch (sig) {
348 #ifdef	SIGINT
349 		case SIGINT:
350 			if (intrptr)
351 				(*intrptr)++;
352 			bosh.intrcnt++;
353 			break;
354 #endif
355 #ifdef	SIGALRM
356 		case SIGALRM:
357 			if (sleeping)
358 				return;
359 			break;
360 #endif
361 	}
362 
363 	if (trapcom[sig] && (trapflg[0] & SIGCLR) == 0)
364 		flag = TRAPSET;
365 	else if (flags & subsh)
366 		done(sig);
367 	else
368 		flag = SIGSET;
369 
370 	trapnote |= flag;
371 	trapflg[sig] |= flag;
372 	trapsig = sig;
373 }
374 
375 int
handle(sig,func)376 handle(sig, func)
377 	int sig;
378 	sigtype func;
379 {
380 	int	ret;
381 	struct sigaction act, oact;
382 
383 	if (func == SIG_IGN && (trapflg[sig] & SIGIGN))
384 		return (0);
385 
386 	/*
387 	 * Ensure that sigaction is only called with valid signal numbers,
388 	 * we can get random values back for oact.sa_handler if the signal
389 	 * number is invalid.
390 	 *
391 	 * XXX Should we enable SA_SIGINFO for SIGCHLD as well?
392 	 *
393 	 * Traps like ERR are past MAX_SIG
394 	 */
395 	if (sig > MINTRAP && sig < MAX_SIG) {
396 		sigemptyset(&act.sa_mask);
397 		act.sa_flags = (sig == SIGSEGV) ? (SA_ONSTACK | SA_SIGINFO) : 0;
398 		act.sa_handler = func;
399 		sigaction(sig, &act, &oact);
400 	}
401 
402 	if (sig >= MINTRAP && sig < MAXTRAP) {	/* Paranoia for Coverity */
403 		if (func == SIG_IGN)
404 			trapflg[sig] |= SIGIGN;
405 	}
406 
407 	/*
408 	 * Special case for signal zero, we can not obtain the previos
409 	 * action by calling sigaction, instead we save it in the variable
410 	 * psig0_func, so we can test it next time through this code
411 	 *
412 	 */
413 	if (sig == 0) {
414 		ret = (psig0_func != func);
415 		psig0_func = func;
416 #ifdef	DO_ERR_TRAP
417 	} else if (sig == ERRTRAP) {
418 		ret = (psigerr_func != func);
419 		psigerr_func = func;
420 #endif
421 	} else {
422 		ret = (func != oact.sa_handler);
423 	}
424 
425 	return (ret);
426 }
427 
428 void
stdsigs()429 stdsigs()
430 {
431 	int	i;
432 #if defined(HAVE_STACK_T) && defined(HAVE_SIGALTSTACK)
433 	stack_t	ss;
434 #ifndef	HAVE_SIGSTKSZ_CONST
435 	char	*sigsegv_stack = alloc(SIGSTKSZ);
436 #endif
437 #endif
438 #ifdef	SIGRTMIN
439 	int rtmin = (int)SIGRTMIN;
440 	int rtmax = (int)SIGRTMAX;
441 #else
442 	int rtmin = -1;
443 	int rtmax = -2;
444 #endif
445 
446 #if defined(HAVE_STACK_T) && defined(HAVE_SIGALTSTACK)
447 	ss.ss_size = SIGSTKSZ;
448 	ss.ss_sp = sigsegv_stack;
449 	ss.ss_flags = 0;
450 	if (sigaltstack(&ss, NULL) == -1) {
451 		error("sigaltstack(2) failed");
452 	}
453 #endif
454 
455 	for (i = 1; i < MAXTRAP; i++) {
456 		if (i == rtmin) {
457 			i = rtmax;
458 			continue;
459 		}
460 		if (sigval[i] == 0)
461 			continue;
462 #ifndef	DO_POSIX_TRAP
463 		if (i != SIGSEGV && ignoring(i))
464 #else
465 		if (ignoring(i))
466 #endif
467 			continue;
468 		handle(i, sigval[i]);
469 	}
470 
471 	/*
472 	 * handle all the realtime signals
473 	 *
474 	 */
475 	for (i = rtmin; i <= rtmax; i++) {
476 		handle(i, done);
477 	}
478 }
479 
480 /*
481  * This function is called just before execve() is called.
482  * It resets the signal handlers to their defaults if the
483  * signals that are either not set (trapcom[i] == NULL) or
484  * set to catch the signal ((trapcom[i][0] != '\0'). Note
485  * that clrsig() only affects signals that have the SIGMOD
486  * flag set in trapflg[i].
487  */
488 void
oldsigs(dofree)489 oldsigs(dofree)
490 	int	dofree;
491 {
492 	int	i;
493 	int	f;
494 	unsigned char	*t;
495 
496 	i = MAXTRAP;
497 	while (i--) {
498 		t = trapcom[i];
499 		f = trapflg[i];
500 		if (t == 0 || *t) {
501 			clrsig(i, dofree);
502 #ifdef	HAVE_VFORK
503 			if ((f & SIGMOD) && !dofree)
504 				f |= SIGCLR;
505 #endif
506 		}
507 		if (dofree)
508 			trapflg[i] = 0;
509 		else
510 			trapflg[i] = f;		/* Remember for restoresigs */
511 	}
512 	if (dofree)
513 		trapnote = 0;
514 }
515 
516 #ifdef	HAVE_VFORK
517 void
restoresigs()518 restoresigs()
519 {
520 	int	i;
521 	int	f;
522 	unsigned char	*t;
523 
524 	i = MAXTRAP;
525 	while (i--) {
526 		t = trapcom[i];
527 		f = trapflg[i];
528 		if ((f & SIGMOD) == 0)		/* If not modified before */
529 			continue;		/* skip this signal	  */
530 		if (t) {
531 			if (*t)
532 				handle(i, fault);
533 			else
534 				handle(i, SIG_IGN);
535 		} else {
536 			handle(i, sigval[i]);
537 		}
538 		trapflg[i] = f & ~SIGCLR;
539 	}
540 }
541 #endif
542 
543 /*
544  * check for traps
545  */
546 void
chktrap()547 chktrap()
548 {
549 	int	i = MAXTRAP;
550 	unsigned char	*t;
551 
552 #ifdef	DO_ERR_TRAP
553 	if (exitval && trapcom[ERRTRAP] != NULL && !traprecurse) {
554 		trapflg[ERRTRAP] = TRAPSET;
555 	}
556 #endif
557 	trapnote &= ~TRAPSET;
558 	while (--i) {
559 		if (trapflg[i] & TRAPSET) {
560 			trapflg[i] &= ~TRAPSET;
561 			if ((t = trapcom[i]) != NULL) {
562 				int	savxit = exitval;
563 				int	savret = retval;
564 				struct excode savex;
565 				struct excode savrex;
566 
567 				savex = ex;
568 				savrex = retex;
569 				retex.ex_signo = i;
570 #ifdef	DO_ERR_TRAP
571 				if (i == ERRTRAP)
572 					retval = exitval;
573 #endif
574 				traprecurse++;
575 				execexp(t, (Intptr_t)0, 0);
576 				traprecurse--;
577 				exitval = savxit;
578 				retval = savret;
579 				ex = savex;
580 				retex = savrex;
581 				exitset();
582 			}
583 		}
584 	}
585 }
586 
587 static int
str2trap(s,sig)588 str2trap(s, sig)
589 	char	*s;
590 	int	*sig;
591 {
592 	if (strcmp("EXIT", s) == 0) {
593 		*sig = EXITTRAP;
594 		return (0);
595 	}
596 #ifdef	DO_ERR_TRAP
597 	else if (strcmp("ERR", s) == 0) {
598 		*sig = ERRTRAP;
599 		return (0);
600 	}
601 #endif
602 	return (-1);
603 }
604 
605 #ifdef	DO_POSIX_TRAP
606 static int
trap2str(sig,buf)607 trap2str(sig, buf)
608 	int	sig;
609 	char	*buf;
610 {
611 	if (sig == EXITTRAP) {
612 		strcpy(buf, "EXIT");
613 		return (0);
614 	}
615 #ifdef	DO_ERR_TRAP
616 	else if (sig == ERRTRAP) {
617 		strcpy(buf, "ERR");
618 		return (0);
619 	}
620 #endif
621 	return (-1);
622 }
623 #endif
624 
625 static void
prtrap(sig)626 prtrap(sig)
627 	int	sig;
628 {
629 #ifdef	DO_POSIX_TRAP
630 	char	buf[SIG2STR_MAX];
631 
632 	prs_buff(UC "trap -- '");
633 	if (trapcom[sig])
634 		prs_buff(trapcom[sig]);
635 	else if (!ignoring(sig))
636 		prs_buff(UC "-");
637 	prs_buff(UC "' ");
638 	if (trap2str(sig, buf) < 0 && sig2str(sig, buf) < 0)
639 		prn_buff(sig);
640 	else
641 		prs_buff(UC buf);
642 #else
643 	prn_buff(sig);
644 	prs_buff((unsigned char *)colon);
645 	prs_buff(trapcom[sig]);
646 #endif
647 	prc_buff(NL);
648 }
649 
650 void
systrap(argc,argv)651 systrap(argc, argv)
652 	int	argc;
653 	char	**argv;
654 {
655 	int sig;
656 	int		hasp = 0;
657 #ifdef	DO_POSIX_TRAP
658 	struct optv	optv;
659 	int		c;
660 
661 	optinit(&optv);
662 	optv.optflag |= OPT_SPC;
663 
664 	while ((c = optnext(argc, UCP argv, &optv, "p", trapuse)) != -1) {
665 		if (c == 0)	/* Was -help */
666 			return;
667 		else if (c == 'p')
668 			hasp++;
669 	}
670 	argv += --optv.optind;
671 	argc -= optv.optind;
672 #endif
673 
674 	if (argc == 1) {
675 		/*
676 		 * print out the current action associated with each signal
677 		 * handled by the shell
678 		 *
679 		 */
680 		for (sig = 0; sig < MAXTRAP; sig++) {
681 			if (trapcom[sig] || hasp)
682 				prtrap(sig);
683 		}
684 	} else {
685 		/*
686 		 * set the action for the list of signals
687 		 *
688 		 * a1 is guaranteed to be != NULL here
689 		 */
690 		char *cmdp = *argv, *a1 = *(argv+1);
691 		BOOL noa1 = FALSE;
692 
693 #ifdef	DO_POSIX_TRAP
694 		if (a1[0] == '-' && a1[1] == '\0') {
695 			noa1++;
696 			++argv;
697 		} else
698 #endif
699 		{
700 			noa1 = (str2trap(a1, &sig) == 0 ||
701 				str2sig(a1, &sig) == 0);
702 			if (noa1 == 0)
703 				++argv;
704 		}
705 		while (*++argv) {
706 			if ((str2trap(*argv, &sig) < 0 &&
707 			    str2sig(*argv, &sig) < 0) ||
708 			    sig >= MAXTRAP || sig < MINTRAP ||
709 #ifndef	DO_POSIX_TRAP
710 			    sig == SIGSEGV) {
711 #else
712 			    0) {
713 #endif
714 				failure((unsigned char *)cmdp, badtrap);
715 			} else if (noa1) {
716 #ifdef	DO_POSIX_TRAP
717 				if (hasp)
718 					prtrap(sig);
719 				else
720 #endif
721 				/*
722 				 * no action specifed so reset the signal
723 				 * to its default disposition
724 				 *
725 				 */
726 				clrsig(sig, TRUE);
727 			} else if (*a1) {
728 				/*
729 				 * set the action associated with the signal
730 				 * to a1
731 				 *
732 				 */
733 				if (trapflg[sig] & SIGMOD || sig == 0 ||
734 				    !ignoring(sig)) {
735 					handle(sig, fault);
736 					trapflg[sig] |= SIGMOD;
737 					replace(&trapcom[sig],
738 						(unsigned char *)a1);
739 				}
740 			} else if (handle(sig, SIG_IGN)) {
741 				/*
742 				 * set the action associated with the signal
743 				 * to SIG_IGN
744 				 *
745 				 */
746 				trapflg[sig] |= SIGMOD;
747 				replace(&trapcom[sig], (unsigned char *)a1);
748 			}
749 		}
750 	}
751 }
752 
753 void
sh_sleep(ticks)754 sh_sleep(ticks)
755 	unsigned int	ticks;
756 {
757 #ifdef	SIGALRM
758 	sigset_t set, oset;
759 	struct sigaction act, oact;
760 
761 
762 	/*
763 	 * add SIGALRM to mask
764 	 */
765 
766 	sigemptyset(&set);
767 	sigaddset(&set, SIGALRM);
768 	sigprocmask(SIG_BLOCK, &set, &oset);
769 
770 	/*
771 	 * catch SIGALRM
772 	 */
773 
774 	sigemptyset(&act.sa_mask);
775 	act.sa_flags = 0;
776 	act.sa_handler = fault;
777 	sigaction(SIGALRM, &act, &oact);
778 
779 	/*
780 	 * start alarm and wait for signal
781 	 */
782 
783 	alarm(ticks);
784 	sleeping = 1;
785 	sigsuspend(&oset);
786 	sleeping = 0;
787 
788 	/*
789 	 * reset alarm, catcher and mask
790 	 */
791 
792 	alarm(0);
793 	sigaction(SIGALRM, &oact, NULL);
794 	sigprocmask(SIG_SETMASK, &oset, 0);
795 #else
796 	sleep(ticks);
797 #endif
798 }
799 
800 /* ARGSUSED */
801 static void
sigsegv(sig,sip,uap)802 sigsegv(sig, sip, uap)
803 	int		sig;
804 	siginfo_t	*sip;
805 	ucontext_t	*uap;
806 {
807 	if (sip == (siginfo_t *)NULL) {
808 		/*
809 		 * This should never happen, but if it does this is all we
810 		 * can do. It can only happen if sigaction(2) for SIGSEGV
811 		 * has been called without SA_SIGINFO being set.
812 		 *
813 		 */
814 
815 		exit(ERROR);
816 	} else {
817 #ifdef	HAVE_SIGINFO_T
818 		if (sip->si_code <= 0) {
819 			/*
820 			 * If we are here then SIGSEGV must have been sent to
821 			 * us from a user process NOT as a result of an
822 			 * internal error within the shell eg
823 			 * kill -SEGV $$
824 			 * will bring us here. So do the normal thing.
825 			 *
826 			 */
827 			fault(sig);
828 		} else {
829 			/*
830 			 * If we are here then there must have been an internal
831 			 * error within the shell to generate SIGSEGV eg
832 			 * the stack is full and we cannot call any more
833 			 * functions (Remeber this signal handler is running
834 			 * on an alternate stack). So we just exit cleanly
835 			 * with an error status (no core file).
836 			 */
837 			exit(ERROR);
838 		}
839 #else
840 		exit(ERROR);
841 #endif
842 	}
843 }
844 
845 static void
set_sigval(sig,fun)846 set_sigval(sig, fun)
847 	int	sig;
848 	void	(*fun) __PR((int));
849 {
850 	if (sig < MAXTRAP)
851 		sigval[sig] = fun;
852 }
853 
854 void
init_sigval()855 init_sigval()
856 {
857 #ifdef	SIGHUP
858 	set_sigval(SIGHUP, done);
859 #endif
860 #ifdef	SIGINT
861 	set_sigval(SIGINT, fault);
862 #endif
863 #ifdef	SIGQUIT
864 	set_sigval(SIGQUIT, fault);
865 #endif
866 #ifdef	SIGILL
867 	set_sigval(SIGILL, done);
868 #endif
869 #ifdef	SIGTRAP
870 	set_sigval(SIGTRAP, done);
871 #endif
872 #ifdef	SIGABRT
873 	set_sigval(SIGABRT, done);
874 #endif
875 #ifdef	SIGIOT
876 	set_sigval(SIGIOT, done);	/* SIGIOT == SIGABRT */
877 #endif
878 #ifdef	SIGEMT
879 	set_sigval(SIGEMT, done);
880 #endif
881 #ifdef	SIGFPE
882 	set_sigval(SIGFPE, done);
883 #endif
884 #ifdef	SIGKILL
885 #ifdef	__set_nullsig__
886 	set_sigval(SIGKILL, 0);
887 #endif
888 #endif
889 #ifdef	SIGBUS
890 	set_sigval(SIGBUS, done);
891 #endif
892 #ifndef	NO_SIGSEGV			/* No sigsegv() for debugging */
893 #ifdef	SIGSEGV
894 	set_sigval(SIGSEGV, (void (*) __PR((int)))sigsegv);
895 #endif
896 #endif
897 #ifdef	SIGSYS
898 	set_sigval(SIGSYS, done);
899 #endif
900 #ifdef	SIGPIPE
901 	set_sigval(SIGPIPE, done);
902 #endif
903 #ifdef	SIGALRM
904 	set_sigval(SIGALRM, done);
905 #endif
906 #ifdef	SIGTERM
907 	set_sigval(SIGTERM, fault);
908 #endif
909 #ifdef	SIGUSR1
910 	set_sigval(SIGUSR1, done);
911 #endif
912 #ifdef	SIGUSR2
913 	set_sigval(SIGUSR2, done);
914 #endif
915 #ifdef	SIGCHLD
916 	set_sigval(SIGCHLD, 0);
917 #endif
918 #ifdef	SIGPWR
919 	set_sigval(SIGPWR, done);
920 #endif
921 #ifdef	SIGWINCH
922 	set_sigval(SIGWINCH, 0);
923 #endif
924 #ifdef	SIGURG
925 	set_sigval(SIGURG, done);
926 #endif
927 #ifdef	SIGPOLL
928 	set_sigval(SIGPOLL, done);
929 #endif
930 #ifdef	SIGSTOP
931 	set_sigval(SIGSTOP, 0);
932 #endif
933 #ifdef	SIGTSTP
934 	set_sigval(SIGTSTP, 0);
935 #endif
936 #ifdef	SIGCONT
937 	set_sigval(SIGCONT, 0);
938 #endif
939 #ifdef	SIGTTIN
940 	set_sigval(SIGTTIN, 0);
941 #endif
942 #ifdef	SIGTTOU
943 	set_sigval(SIGTTOU, 0);
944 #endif
945 #ifdef	SIGVTALRM
946 	set_sigval(SIGVTALRM, done);
947 #endif
948 #ifndef	NO_SIGPROF			/* No SIGPROF for gprof */
949 #ifdef	SIGPROF
950 	set_sigval(SIGPROF, done);
951 #endif
952 #endif
953 #ifdef	SIGXCPU
954 	set_sigval(SIGXCPU, done);
955 #endif
956 #ifdef	SIGXFSZ
957 	set_sigval(SIGXFSZ, done);
958 #endif
959 #ifdef	SIGWAITING
960 	set_sigval(SIGWAITING, 0);
961 #endif
962 #ifdef	SIGLWP
963 	set_sigval(SIGLWP, 0);
964 #endif
965 #ifdef	SIGFREEZE
966 	set_sigval(SIGFREEZE, 0);
967 #endif
968 #ifdef	SIGTHAW
969 	set_sigval(SIGTHAW, 0);
970 #endif
971 
972 #ifdef	SIGSTKFLT
973 	set_sigval(SIGSTKFLT, done);
974 #endif
975 }
976