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 (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /* Copyright (c) 1988 AT&T */
22 /* All Rights Reserved */
23 /*
24  * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
25  * Use is subject to license terms.
26  */
27 /*
28  * Copyright 2006-2020 J. Schilling
29  *
30  * @(#)setsig.c	1.11 20/09/06 J. Schilling
31  */
32 #if defined(sun)
33 #pragma ident "@(#)setsig.c 1.11 20/09/06 J. Schilling"
34 #endif
35 /*
36  * @(#)setsig.c 1.8 06/12/12
37  */
38 
39 #if defined(sun)
40 #pragma ident	"@(#)setsig.c"
41 #pragma ident	"@(#)sccs:lib/mpwlib/setsig.c"
42 #endif
43 # include       <defines.h>
44 # include       <i18n.h>
45 # include	<signal.h>
46 
47 /*
48 	General-purpose signal setting routine.
49 	All non-ignored, non-caught signals are caught.
50 	If a signal other than hangup, interrupt, or quit is caught,
51 	a "user-oriented" message is printed on file descriptor 2 with
52 	a number for help(I).
53 	If hangup, interrupt or quit is caught, that signal
54 	is set to ignore.
55 	Termination is like that of "fatal",
56 	via "clean_up(sig)" (sig is the signal number)
57 	and "exit(userexit(1))".
58 
59 	If the file "dump.core" exists in the current directory
60 	the function commits
61 	suicide to produce a core dump
62 	(after calling clean_up, but before calling userexit).
63 */
64 
65 extern	void	(*f_clean_up) __PR((void));
66 
67 static struct sigs {
68 	int	signo;
69 	char	*msg;
70 } Mesg[] = {
71 #ifdef	SIGILL
72 	{ SIGILL,	"Illegal instruction" },
73 #endif
74 #ifdef	SIGTRAP
75 	{ SIGTRAP,	"Trace/BPT trap" },
76 #endif
77 #ifdef	SIGIOT
78 	{ SIGIOT,	"IOT trap" },
79 #endif
80 #ifdef	SIGEMT
81 	{ SIGEMT,	"EMT trap" },
82 #endif
83 #ifdef	SIGFPE
84 	{ SIGFPE,	"Floating exception" },
85 #endif
86 #ifdef	SIGKILL
87 	{ SIGKILL,	"Killed" },
88 #endif
89 #ifdef	SIGBUS
90 	{ SIGBUS,	"Bus error" },
91 #endif
92 #ifdef	SIGSEGV
93 	{ SIGSEGV,	"Memory fault" },
94 #endif
95 #ifdef	SIGSYS
96 	{ SIGSYS,	"Bad system call" },
97 #endif
98 #ifdef	__pipe__handler
99 #ifdef	SIGPIPE
100 	{ SIGPIPE,	NULL },
101 #endif
102 #endif
103 #ifdef	SIGALRM
104 	{ SIGALRM,	"Alarm clock" },
105 #endif
106 	{ 0, NULL }
107 };
108 
109 static void setsig1	__PR((int sig));
110 
111 void
setsig()112 setsig()
113 {
114 	register int j;
115 	register void (*n) __PR((int));
116 
117 	for (j = 0; Mesg[j].signo != 0; j++) {
118 #ifdef	SETSIG_NO_SIGBUS
119 		/*
120 		 * Original behavior was not to catch SIGBUS.
121 		 * #define SETSIG_NO_SIGBUS to get historic behavior.
122 		 */
123 		if (Mesg[j].signo == SIGBUS)
124 			continue;
125 #endif
126 		if ((n = signal(Mesg[j].signo, setsig1)) != NULL)
127 			signal(Mesg[j].signo, n);
128 	}
129 }
130 
131 
132 static void
setsig1(sig)133 setsig1(sig)
134 int sig;
135 {
136 	static int die = 0;
137 		int	j;
138 
139 	if (die++) {
140 #ifdef	SIGIOT
141 		signal(SIGIOT, SIG_DFL);
142 #endif
143 #ifdef	SIGEMT
144 		signal(SIGEMT, SIG_DFL);
145 #endif
146 #ifdef	SIGILL
147 		signal(SIGILL, SIG_DFL);
148 #endif
149 		exit(1);
150 	}
151 
152 	for (j = 0; Mesg[j].msg != NULL; j++)
153 		if (Mesg[j].signo == sig)
154 			break;
155 
156 	if (Mesg[j].msg) {
157 		(void) write(2, gettext("SIGNAL: "), length("SIGNAL: "));
158 		(void) write(2, gettext(Mesg[j].msg), length(Mesg[j].msg));
159 		(void) write(2, NOGETTEXT(" (ut12)\n"), length(" (ut12)\n"));
160 	}
161 	else
162 		signal(sig, SIG_IGN);
163 	(*f_clean_up)();
164 	if(open(NOGETTEXT("dump.core"), O_RDONLY|O_BINARY) > 0) {
165 		/*
166 		 * If the file "dump.core" exists in the current directory and
167 		 * is readable for us, dump the core via abort().
168 		 */
169 #ifdef	SIGIOT
170 		signal(SIGIOT, SIG_DFL);
171 #endif
172 #ifdef	SIGEMT
173 		signal(SIGEMT, SIG_DFL);
174 #endif
175 #ifdef	SIGILL
176 		signal(SIGILL, SIG_DFL);
177 #endif
178 		abort();
179 	}
180 	exit(userexit(1));
181 }
182