make vfs & filesystems use failable copying
[minix3.git] / test / ipc / lib / tst_sig.c
blob413fe525db6160657a7f6adc11b7aca9d67be448
1 /*
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.
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.
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.
23 * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
24 * Mountain View, CA 94043, or:
26 * http://www.sgi.com
28 * For further information regarding this notice, see:
30 * http://oss.sgi.com/projects/GenInfo/NoticeExplan/
33 /*****************************************************************************
34 OS Testing - Silicon Graphics, Inc.
36 FUNCTION IDENTIFIER : tst_sig Set up for unexpected signals.
38 AUTHOR : David D. Fenner
40 CO-PILOT : Bill Roske
42 DATE STARTED : 06/06/90
44 This module may be linked with c-modules requiring unexpected
45 signal handling. The parameters to tst_sig are as follows:
47 fork_flag - set to FORK or NOFORK depending upon whether the
48 calling program executes a fork() system call. It
49 is normally the case that the calling program treats
50 SIGCLD as an expected signal if fork() is being used.
52 handler - a pointer to the unexpected signal handler to
53 be executed after an unexpected signal has been
54 detected. If handler is set to DEF_HANDLER, a
55 default handler is used. This routine should be
56 declared as function returning an int.
58 cleanup - a pointer to a cleanup routine to be executed
59 by the unexpected signal handler before tst_exit is
60 called. This parameter is set to NULL if no cleanup
61 routine is required. An external variable, T_cleanup
62 is set so that other user-defined handlers have
63 access to the cleanup routine. This routine should be
64 declared as returning type void.
66 ***************************************************************************/
68 #include <errno.h>
69 #include <string.h>
70 #include <signal.h>
71 #include <unistd.h>
72 #include "test.h"
74 #define MAXMESG 150 /* size of mesg string sent to tst_res */
76 void (*T_cleanup)(void); /* pointer to cleanup function */
78 /****************************************************************************
79 * STD_COPIES is defined in parse_opts.c but is externed here in order to
80 * test whether SIGCHILD should be ignored or not.
81 ***************************************************************************/
82 extern int STD_COPIES;
84 static void def_handler(int); /* default signal handler */
85 static void (*tst_setup_signal( int, void (*)(int)))(int);
87 /****************************************************************************
88 * tst_sig() : set-up to catch unexpected signals. fork_flag is set to NOFORK
89 * if SIGCLD is to be an "unexpected signal", otherwise it is set to
90 * FORK. cleanup points to a cleanup routine to be executed before
91 * tst_exit is called (cleanup is set to NULL if no cleanup is desired).
92 * handler is a pointer to the signal handling routine (if handler is
93 * set to NULL, a default handler is used).
94 ***************************************************************************/
96 void
97 tst_sig(int fork_flag, void (*handler)(int), void (*cleanup)(void))
99 char mesg[MAXMESG]; /* message buffer for tst_res */
100 int sig;
101 #ifdef _SC_SIGRT_MIN
102 long sigrtmin, sigrtmax;
103 #endif
106 * save T_cleanup and handler function pointers
108 T_cleanup = cleanup; /* used by default handler */
110 if (handler == DEF_HANDLER) {
111 /* use default handler */
112 handler = def_handler;
115 #ifdef _SC_SIGRT_MIN
116 sigrtmin = sysconf(_SC_SIGRT_MIN);
117 sigrtmax = sysconf(_SC_SIGRT_MAX);
118 #endif
121 * now loop through all signals and set the handlers
124 for (sig = 1; sig < NSIG; sig++) {
126 * SIGKILL is never unexpected.
127 * SIGCLD is only unexpected when
128 * no forking is being done.
129 * SIGINFO is used for file quotas and should be expected
132 #ifdef _SC_SIGRT_MIN
133 if (sig >= sigrtmin && sig <= sigrtmax)
134 continue;
135 #endif
137 switch (sig) {
138 case SIGKILL:
139 case SIGSTOP:
140 case SIGCONT:
141 #if !defined(_SC_SIGRT_MIN) && defined(__SIGRTMIN) && defined(__SIGRTMAX)
142 /* Ignore all real-time signals */
143 case __SIGRTMIN:
144 case __SIGRTMIN+1:
145 case __SIGRTMIN+2:
146 case __SIGRTMIN+3:
147 case __SIGRTMIN+4:
148 case __SIGRTMIN+5:
149 case __SIGRTMIN+6:
150 case __SIGRTMIN+7:
151 case __SIGRTMIN+8:
152 case __SIGRTMIN+9:
153 case __SIGRTMIN+10:
154 case __SIGRTMIN+11:
155 case __SIGRTMIN+12:
156 case __SIGRTMIN+13:
157 case __SIGRTMIN+14:
158 case __SIGRTMIN+15:
159 /* __SIGRTMIN is 37 on HPPA rather than 32 *
160 * as on i386, etc. */
161 #if !defined(__hppa__)
162 case __SIGRTMAX-15:
163 case __SIGRTMAX-14:
164 case __SIGRTMAX-13:
165 case __SIGRTMAX-12:
166 case __SIGRTMAX-11:
167 #endif
168 case __SIGRTMAX-10:
169 case __SIGRTMAX-9:
170 case __SIGRTMAX-8:
171 case __SIGRTMAX-7:
172 case __SIGRTMAX-6:
173 case __SIGRTMAX-5:
174 case __SIGRTMAX-4:
175 case __SIGRTMAX-3:
176 case __SIGRTMAX-2:
177 case __SIGRTMAX-1:
178 case __SIGRTMAX:
179 #endif
180 #ifdef CRAY
181 case SIGINFO:
182 case SIGRECOVERY: /* allow chkpnt/restart */
183 #endif /* CRAY */
185 #ifdef SIGSWAP
186 case SIGSWAP:
187 #endif /* SIGSWAP */
189 #ifdef SIGCKPT
190 case SIGCKPT:
191 #endif
192 #ifdef SIGRESTART
193 case SIGRESTART:
194 #endif
196 * pthread-private signals SIGPTINTR and SIGPTRESCHED.
197 * Setting a handler for these signals is disallowed when
198 * the binary is linked against libpthread.
200 #ifdef SIGPTINTR
201 case SIGPTINTR:
202 #endif /* SIGPTINTR */
203 #ifdef SIGPTRESCHED
204 case SIGPTRESCHED:
205 #endif /* SIGPTRESCHED */
206 #ifdef _SIGRESERVE
207 case _SIGRESERVE:
208 #endif
209 #ifdef _SIGDIL
210 case _SIGDIL:
211 #endif
212 #ifdef _SIGCANCEL
213 case _SIGCANCEL:
214 #endif
215 #ifdef _SIGGFAULT
216 case _SIGGFAULT:
217 #endif
218 break;
220 case SIGCLD:
221 if ( fork_flag == FORK || STD_COPIES > 1)
222 continue;
224 default:
225 if (tst_setup_signal(sig, handler) == SIG_ERR) {
226 (void) sprintf(mesg,
227 "signal() failed for signal %d. error:%d %s.",
228 sig, errno, strerror(errno));
229 tst_resm(TWARN, mesg);
231 break;
233 #ifdef __sgi
234 /* On irix (07/96), signal() fails when signo is 33 or higher */
235 if ( sig+1 >= 33 )
236 break;
237 #endif /* __sgi */
239 } /* endfor */
244 /****************************************************************************
245 * def_handler() : default signal handler that is invoked when
246 * an unexpected signal is caught.
247 ***************************************************************************/
249 static void
250 def_handler(int sig)
254 * Break remaining test cases, do any cleanup, then exit
256 tst_brkm(TBROK, 0, "Unexpected signal %d received.", sig);
258 /* now cleanup and exit */
259 if (T_cleanup) {
260 (*T_cleanup)();
263 tst_exit();
267 * tst_setup_signal - A function like signal(), but we have
268 * control over its personality.
270 static void (*tst_setup_signal( int sig, void (*handler)(int)))(int)
272 struct sigaction my_act,old_act;
273 int ret;
275 my_act.sa_handler = handler;
276 my_act.sa_flags = SA_RESTART;
277 sigemptyset(&my_act.sa_mask);
279 ret = sigaction(sig, &my_act, &old_act);
281 if ( ret == 0 )
282 return( old_act.sa_handler );
283 else
284 return( SIG_ERR );