blob: 8896acceba9097866da4e7f53a067c7b08f2e34e [file] [log] [blame]
alaffincc2e5552000-07-27 17:13:18 +00001/*
2 * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of version 2 of the GNU General Public License as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it would be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11 *
12 * Further, this software is distributed without any warranty that it is
13 * free of the rightful claim of any third person regarding infringement
14 * or the like. Any license provided herein, whether implied or
15 * otherwise, applies only to this software file. Patent licenses, if
16 * any, provided herein do not apply to combinations of this program with
17 * other software, or any other product whatsoever.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write the Free Software Foundation, Inc., 59
21 * Temple Place - Suite 330, Boston MA 02111-1307, USA.
22 *
23 * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
24 * Mountain View, CA 94043, or:
25 *
26 * http://www.sgi.com
27 *
28 * For further information regarding this notice, see:
29 *
30 * http://oss.sgi.com/projects/GenInfo/NoticeExplan/
31 */
32
robbiew3e36a842003-11-25 16:04:28 +000033/* $Id: tst_sig.c,v 1.8 2003/11/25 16:04:28 robbiew Exp $ */
alaffincc2e5552000-07-27 17:13:18 +000034
35/*****************************************************************************
36 OS Testing - Silicon Graphics, Inc.
37
38 FUNCTION IDENTIFIER : tst_sig Set up for unexpected signals.
39
40 AUTHOR : David D. Fenner
41
42 CO-PILOT : Bill Roske
43
44 DATE STARTED : 06/06/90
45
46 This module may be linked with c-modules requiring unexpected
47 signal handling. The parameters to tst_sig are as follows:
48
49 fork_flag - set to FORK or NOFORK depending upon whether the
50 calling program executes a fork() system call. It
51 is normally the case that the calling program treats
52 SIGCLD as an expected signal if fork() is being used.
53
54 handler - a pointer to the unexpected signal handler to
55 be executed after an unexpected signal has been
56 detected. If handler is set to DEF_HANDLER, a
57 default handler is used. This routine should be
58 declared as function returning an int.
59
60 cleanup - a pointer to a cleanup routine to be executed
61 by the unexpected signal handler before tst_exit is
62 called. This parameter is set to NULL if no cleanup
63 routine is required. An external variable, T_cleanup
64 is set so that other user-defined handlers have
65 access to the cleanup routine. This routine should be
66 declared as returning type void.
67
68***************************************************************************/
69
alaffincc2e5552000-07-27 17:13:18 +000070#include <errno.h>
71#include <string.h>
72#include <signal.h>
73#include "test.h"
74
75#define MAXMESG 150 /* size of mesg string sent to tst_res */
76
77void (*T_cleanup)(); /* pointer to cleanup function */
78
nstrazd8522012001-06-01 19:46:13 +000079/****************************************************************************
80 * STD_COPIES is defined in parse_opts.c but is externed here in order to
81 * test whether SIGCHILD should be ignored or not.
82 ***************************************************************************/
83extern int STD_COPIES;
84
alaffincc2e5552000-07-27 17:13:18 +000085static void def_handler(); /* default signal handler */
alaffin3c8699d2000-09-07 14:34:44 +000086static void (*tst_setup_signal( int, void (*)(int)))(int);
alaffincc2e5552000-07-27 17:13:18 +000087
88/****************************************************************************
89 * tst_sig() : set-up to catch unexpected signals. fork_flag is set to NOFORK
90 * if SIGCLD is to be an "unexpected signal", otherwise it is set to
91 * FORK. cleanup points to a cleanup routine to be executed before
92 * tst_exit is called (cleanup is set to NULL if no cleanup is desired).
93 * handler is a pointer to the signal handling routine (if handler is
94 * set to NULL, a default handler is used).
95 ***************************************************************************/
96
97void
nstraz94181082000-08-30 18:43:38 +000098tst_sig(int fork_flag, void (*handler)(), void (*cleanup)())
alaffincc2e5552000-07-27 17:13:18 +000099{
alaffincc2e5552000-07-27 17:13:18 +0000100 char mesg[MAXMESG]; /* message buffer for tst_res */
101 int sig;
102
103 /*
104 * save T_cleanup and handler function pointers
105 */
106 T_cleanup = cleanup; /* used by default handler */
107
108 if (handler == DEF_HANDLER) {
109 /* use default handler */
110 handler = def_handler;
111 }
robbiewdf450432003-04-28 21:37:40 +0000112
alaffincc2e5552000-07-27 17:13:18 +0000113 /*
114 * now loop through all signals and set the handlers
115 */
116
117 for (sig = 1; sig < NSIG; sig++) {
118 /*
119 * SIGKILL is never unexpected.
120 * SIGCLD is only unexpected when
121 * no forking is being done.
122 * SIGINFO is used for file quotas and should be expected
123 */
124
125 switch (sig) {
126 case SIGKILL:
127 case SIGSTOP:
128 case SIGCONT:
robbiew3e36a842003-11-25 16:04:28 +0000129 /* Ignore all real-time signals */
130 case __SIGRTMIN:
131 case __SIGRTMIN+1:
132 case __SIGRTMIN+2:
133 case __SIGRTMIN+3:
134 case __SIGRTMIN+4:
135 case __SIGRTMIN+5:
136 case __SIGRTMIN+6:
137 case __SIGRTMIN+7:
138 case __SIGRTMIN+8:
139 case __SIGRTMIN+9:
140 case __SIGRTMIN+10:
141 case __SIGRTMIN+11:
142 case __SIGRTMIN+12:
143 case __SIGRTMIN+13:
144 case __SIGRTMIN+14:
145 case __SIGRTMIN+15:
146 case __SIGRTMAX-15:
147 case __SIGRTMAX-14:
148 case __SIGRTMAX-13:
149 case __SIGRTMAX-12:
150 case __SIGRTMAX-11:
151 case __SIGRTMAX-10:
152 case __SIGRTMAX-9:
153 case __SIGRTMAX-8:
154 case __SIGRTMAX-7:
155 case __SIGRTMAX-6:
156 case __SIGRTMAX-5:
157 case __SIGRTMAX-4:
158 case __SIGRTMAX-3:
159 case __SIGRTMAX-2:
160 case __SIGRTMAX-1:
161 case __SIGRTMAX:
alaffincc2e5552000-07-27 17:13:18 +0000162#ifdef CRAY
163 case SIGINFO:
164 case SIGRECOVERY: /* allow chkpnt/restart */
165#endif /* CRAY */
166
167#ifdef SIGSWAP
robbiew3e36a842003-11-25 16:04:28 +0000168 case SIGSWAP:
alaffincc2e5552000-07-27 17:13:18 +0000169#endif /* SIGSWAP */
170
171#ifdef SIGCKPT
172 case SIGCKPT:
173#endif
174#ifdef SIGRESTART
175 case SIGRESTART:
176#endif
177 /*
178 * pthread-private signals SIGPTINTR and SIGPTRESCHED.
179 * Setting a handler for these signals is disallowed when
180 * the binary is linked against libpthread.
181 */
182#ifdef SIGPTINTR
183 case SIGPTINTR:
184#endif /* SIGPTINTR */
185#ifdef SIGPTRESCHED
186 case SIGPTRESCHED:
187#endif /* SIGPTRESCHED */
188
189 break;
190
191 case SIGCLD:
nstrazd8522012001-06-01 19:46:13 +0000192 if ( fork_flag == FORK || STD_COPIES > 1)
alaffincc2e5552000-07-27 17:13:18 +0000193 continue;
194
195 default:
alaffin3c8699d2000-09-07 14:34:44 +0000196 if (tst_setup_signal(sig, handler) == SIG_ERR) {
alaffincc2e5552000-07-27 17:13:18 +0000197 (void) sprintf(mesg,
198 "signal() failed for signal %d. error:%d %s.",
199 sig, errno, strerror(errno));
200 tst_resm(TWARN, mesg);
201 }
202 break;
203 }
204#ifdef __sgi
205 /* On irix (07/96), signal() fails when signo is 33 or higher */
206 if ( sig+1 >= 33 )
207 break;
208#endif /* __sgi */
209
210 } /* endfor */
211}
212
213
214
215/****************************************************************************
216 * def_handler() : default signal handler that is invoked when
217 * an unexpected signal is caught.
218 ***************************************************************************/
219
220static void
nstraz94181082000-08-30 18:43:38 +0000221def_handler(int sig)
alaffincc2e5552000-07-27 17:13:18 +0000222{
alaffincc2e5552000-07-27 17:13:18 +0000223
224 /*
225 * Break remaining test cases, do any cleanup, then exit
226 */
alaffin3c8699d2000-09-07 14:34:44 +0000227 tst_brkm(TBROK, 0, "Unexpected signal %d received.", sig);
alaffincc2e5552000-07-27 17:13:18 +0000228
229 /* now cleanup and exit */
230 if (T_cleanup) {
231 (*T_cleanup)();
232 }
233
234 tst_exit();
235}
alaffin3c8699d2000-09-07 14:34:44 +0000236
237/*
238 * tst_setup_signal - A function like signal(), but we have
239 * control over its personality.
240 */
241static void (*tst_setup_signal( int sig, void (*handler)(int)))(int)
242{
243 struct sigaction my_act,old_act;
244 int ret;
245
246 my_act.sa_handler = handler;
247 my_act.sa_flags = SA_RESTART;
248 sigemptyset(&my_act.sa_mask);
249
250 ret = sigaction(sig, &my_act, &old_act);
251
252 if ( ret == 0 )
253 return( old_act.sa_handler );
254 else
255 return( SIG_ERR );
256}
257