1f08c3bdfSopenharmony_ci/*
2f08c3bdfSopenharmony_ci * Copyright (c) 2000 Silicon Graphics, Inc.  All Rights Reserved.
3f08c3bdfSopenharmony_ci *
4f08c3bdfSopenharmony_ci * This program is free software; you can redistribute it and/or modify it
5f08c3bdfSopenharmony_ci * under the terms of version 2 of the GNU General Public License as
6f08c3bdfSopenharmony_ci * published by the Free Software Foundation.
7f08c3bdfSopenharmony_ci *
8f08c3bdfSopenharmony_ci * This program is distributed in the hope that it would be useful, but
9f08c3bdfSopenharmony_ci * WITHOUT ANY WARRANTY; without even the implied warranty of
10f08c3bdfSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11f08c3bdfSopenharmony_ci *
12f08c3bdfSopenharmony_ci * Further, this software is distributed without any warranty that it is
13f08c3bdfSopenharmony_ci * free of the rightful claim of any third person regarding infringement
14f08c3bdfSopenharmony_ci * or the like.  Any license provided herein, whether implied or
15f08c3bdfSopenharmony_ci * otherwise, applies only to this software file.  Patent licenses, if
16f08c3bdfSopenharmony_ci * any, provided herein do not apply to combinations of this program with
17f08c3bdfSopenharmony_ci * other software, or any other product whatsoever.
18f08c3bdfSopenharmony_ci *
19f08c3bdfSopenharmony_ci * You should have received a copy of the GNU General Public License along
20f08c3bdfSopenharmony_ci * with this program; if not, write the Free Software Foundation, Inc.,
21f08c3bdfSopenharmony_ci * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22f08c3bdfSopenharmony_ci *
23f08c3bdfSopenharmony_ci * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
24f08c3bdfSopenharmony_ci * Mountain View, CA  94043, or:
25f08c3bdfSopenharmony_ci *
26f08c3bdfSopenharmony_ci * http://www.sgi.com
27f08c3bdfSopenharmony_ci *
28f08c3bdfSopenharmony_ci * For further information regarding this notice, see:
29f08c3bdfSopenharmony_ci *
30f08c3bdfSopenharmony_ci * http://oss.sgi.com/projects/GenInfo/NoticeExplan/
31f08c3bdfSopenharmony_ci */
32f08c3bdfSopenharmony_ci
33f08c3bdfSopenharmony_ci/* $Id: tst_sig.c,v 1.13 2009/08/28 09:29:01 vapier Exp $ */
34f08c3bdfSopenharmony_ci
35f08c3bdfSopenharmony_ci/*****************************************************************************
36f08c3bdfSopenharmony_ci	OS Testing  - Silicon Graphics, Inc.
37f08c3bdfSopenharmony_ci
38f08c3bdfSopenharmony_ci	FUNCTION IDENTIFIER : tst_sig  Set up for unexpected signals.
39f08c3bdfSopenharmony_ci
40f08c3bdfSopenharmony_ci	AUTHOR          : David D. Fenner
41f08c3bdfSopenharmony_ci
42f08c3bdfSopenharmony_ci	CO-PILOT        : Bill Roske
43f08c3bdfSopenharmony_ci
44f08c3bdfSopenharmony_ci	DATE STARTED    : 06/06/90
45f08c3bdfSopenharmony_ci
46f08c3bdfSopenharmony_ci	This module may be linked with c-modules requiring unexpected
47f08c3bdfSopenharmony_ci	signal handling.  The parameters to tst_sig are as follows:
48f08c3bdfSopenharmony_ci
49f08c3bdfSopenharmony_ci		fork_flag - set to FORK or NOFORK depending upon whether the
50f08c3bdfSopenharmony_ci			calling program executes a fork() system call.  It
51f08c3bdfSopenharmony_ci			is normally the case that the calling program treats
52f08c3bdfSopenharmony_ci			SIGCHLD as an expected signal if fork() is being used.
53f08c3bdfSopenharmony_ci
54f08c3bdfSopenharmony_ci		handler - a pointer to the unexpected signal handler to
55f08c3bdfSopenharmony_ci			be executed after an unexpected signal has been
56f08c3bdfSopenharmony_ci			detected.  If handler is set to DEF_HANDLER, a
57f08c3bdfSopenharmony_ci			default handler is used.  This routine should be
58f08c3bdfSopenharmony_ci			declared as function returning an int.
59f08c3bdfSopenharmony_ci
60f08c3bdfSopenharmony_ci		cleanup - a pointer to a cleanup routine to be executed
61f08c3bdfSopenharmony_ci			by the unexpected signal handler before tst_exit is
62f08c3bdfSopenharmony_ci			called.  This parameter is set to NULL if no cleanup
63f08c3bdfSopenharmony_ci			routine is required.  An external variable, T_cleanup
64f08c3bdfSopenharmony_ci			is set so that other user-defined handlers have
65f08c3bdfSopenharmony_ci			access to the cleanup routine.  This routine should be
66f08c3bdfSopenharmony_ci			declared as returning type void.
67f08c3bdfSopenharmony_ci
68f08c3bdfSopenharmony_ci***************************************************************************/
69f08c3bdfSopenharmony_ci
70f08c3bdfSopenharmony_ci#include <errno.h>
71f08c3bdfSopenharmony_ci#include <string.h>
72f08c3bdfSopenharmony_ci#include <signal.h>
73f08c3bdfSopenharmony_ci#include <unistd.h>
74f08c3bdfSopenharmony_ci#include "test.h"
75f08c3bdfSopenharmony_ci#include "lapi/signal.h"
76f08c3bdfSopenharmony_ci
77f08c3bdfSopenharmony_ci#define MAXMESG 150		/* size of mesg string sent to tst_res */
78f08c3bdfSopenharmony_ci
79f08c3bdfSopenharmony_cistatic void (*T_cleanup) ();
80f08c3bdfSopenharmony_ci
81f08c3bdfSopenharmony_cistatic void def_handler();	/* default signal handler */
82f08c3bdfSopenharmony_cistatic void (*tst_setup_signal(int, void (*)(int))) (int);
83f08c3bdfSopenharmony_ci
84f08c3bdfSopenharmony_ci/****************************************************************************
85f08c3bdfSopenharmony_ci * tst_sig() : set-up to catch unexpected signals.  fork_flag is set to NOFORK
86f08c3bdfSopenharmony_ci *    if SIGCHLD is to be an "unexpected signal", otherwise it is set to
87f08c3bdfSopenharmony_ci *    FORK.  cleanup points to a cleanup routine to be executed before
88f08c3bdfSopenharmony_ci *    tst_exit is called (cleanup is set to NULL if no cleanup is desired).
89f08c3bdfSopenharmony_ci *    handler is a pointer to the signal handling routine (if handler is
90f08c3bdfSopenharmony_ci *    set to NULL, a default handler is used).
91f08c3bdfSopenharmony_ci ***************************************************************************/
92f08c3bdfSopenharmony_ci
93f08c3bdfSopenharmony_civoid tst_sig(int fork_flag, void (*handler) (), void (*cleanup) ())
94f08c3bdfSopenharmony_ci{
95f08c3bdfSopenharmony_ci	int sig;
96f08c3bdfSopenharmony_ci#ifdef _SC_SIGRT_MIN
97f08c3bdfSopenharmony_ci	long sigrtmin, sigrtmax;
98f08c3bdfSopenharmony_ci#endif
99f08c3bdfSopenharmony_ci
100f08c3bdfSopenharmony_ci	/*
101f08c3bdfSopenharmony_ci	 * save T_cleanup and handler function pointers
102f08c3bdfSopenharmony_ci	 */
103f08c3bdfSopenharmony_ci	T_cleanup = cleanup;	/* used by default handler */
104f08c3bdfSopenharmony_ci
105f08c3bdfSopenharmony_ci	if (handler == DEF_HANDLER) {
106f08c3bdfSopenharmony_ci		/* use default handler */
107f08c3bdfSopenharmony_ci		handler = def_handler;
108f08c3bdfSopenharmony_ci	}
109f08c3bdfSopenharmony_ci#ifdef _SC_SIGRT_MIN
110f08c3bdfSopenharmony_ci	sigrtmin = sysconf(_SC_SIGRT_MIN);
111f08c3bdfSopenharmony_ci	sigrtmax = sysconf(_SC_SIGRT_MAX);
112f08c3bdfSopenharmony_ci#endif
113f08c3bdfSopenharmony_ci
114f08c3bdfSopenharmony_ci	/*
115f08c3bdfSopenharmony_ci	 * now loop through all signals and set the handlers
116f08c3bdfSopenharmony_ci	 */
117f08c3bdfSopenharmony_ci
118f08c3bdfSopenharmony_ci	for (sig = 1; sig < NSIG; sig++) {
119f08c3bdfSopenharmony_ci		/*
120f08c3bdfSopenharmony_ci		 * SIGKILL is never unexpected.
121f08c3bdfSopenharmony_ci		 * SIGCHLD is only unexpected when
122f08c3bdfSopenharmony_ci		 *    no forking is being done.
123f08c3bdfSopenharmony_ci		 * SIGINFO is used for file quotas and should be expected
124f08c3bdfSopenharmony_ci		 */
125f08c3bdfSopenharmony_ci
126f08c3bdfSopenharmony_ci#ifdef _SC_SIGRT_MIN
127f08c3bdfSopenharmony_ci		if (sig >= sigrtmin && sig <= sigrtmax)
128f08c3bdfSopenharmony_ci			continue;
129f08c3bdfSopenharmony_ci#endif
130f08c3bdfSopenharmony_ci
131f08c3bdfSopenharmony_ci		switch (sig) {
132f08c3bdfSopenharmony_ci		case SIGKILL:
133f08c3bdfSopenharmony_ci		case SIGSTOP:
134f08c3bdfSopenharmony_ci		case SIGCONT:
135f08c3bdfSopenharmony_ci#if !defined(_SC_SIGRT_MIN) && defined(__SIGRTMIN) && defined(__SIGRTMAX)
136f08c3bdfSopenharmony_ci			/* Ignore all real-time signals */
137f08c3bdfSopenharmony_ci		case __SIGRTMIN:
138f08c3bdfSopenharmony_ci		case __SIGRTMIN + 1:
139f08c3bdfSopenharmony_ci		case __SIGRTMIN + 2:
140f08c3bdfSopenharmony_ci		case __SIGRTMIN + 3:
141f08c3bdfSopenharmony_ci		case __SIGRTMIN + 4:
142f08c3bdfSopenharmony_ci		case __SIGRTMIN + 5:
143f08c3bdfSopenharmony_ci		case __SIGRTMIN + 6:
144f08c3bdfSopenharmony_ci		case __SIGRTMIN + 7:
145f08c3bdfSopenharmony_ci		case __SIGRTMIN + 8:
146f08c3bdfSopenharmony_ci		case __SIGRTMIN + 9:
147f08c3bdfSopenharmony_ci		case __SIGRTMIN + 10:
148f08c3bdfSopenharmony_ci		case __SIGRTMIN + 11:
149f08c3bdfSopenharmony_ci		case __SIGRTMIN + 12:
150f08c3bdfSopenharmony_ci		case __SIGRTMIN + 13:
151f08c3bdfSopenharmony_ci		case __SIGRTMIN + 14:
152f08c3bdfSopenharmony_ci		case __SIGRTMIN + 15:
153f08c3bdfSopenharmony_ci/* __SIGRTMIN is 37 on HPPA rather than 32 *
154f08c3bdfSopenharmony_ci * as on i386, etc.                        */
155f08c3bdfSopenharmony_ci#if !defined(__hppa__)
156f08c3bdfSopenharmony_ci		case __SIGRTMAX - 15:
157f08c3bdfSopenharmony_ci		case __SIGRTMAX - 14:
158f08c3bdfSopenharmony_ci		case __SIGRTMAX - 13:
159f08c3bdfSopenharmony_ci		case __SIGRTMAX - 12:
160f08c3bdfSopenharmony_ci		case __SIGRTMAX - 11:
161f08c3bdfSopenharmony_ci#endif
162f08c3bdfSopenharmony_ci		case __SIGRTMAX - 10:
163f08c3bdfSopenharmony_ci		case __SIGRTMAX - 9:
164f08c3bdfSopenharmony_ci		case __SIGRTMAX - 8:
165f08c3bdfSopenharmony_ci		case __SIGRTMAX - 7:
166f08c3bdfSopenharmony_ci		case __SIGRTMAX - 6:
167f08c3bdfSopenharmony_ci		case __SIGRTMAX - 5:
168f08c3bdfSopenharmony_ci		case __SIGRTMAX - 4:
169f08c3bdfSopenharmony_ci		case __SIGRTMAX - 3:
170f08c3bdfSopenharmony_ci		case __SIGRTMAX - 2:
171f08c3bdfSopenharmony_ci		case __SIGRTMAX - 1:
172f08c3bdfSopenharmony_ci		case __SIGRTMAX:
173f08c3bdfSopenharmony_ci#endif
174f08c3bdfSopenharmony_ci#ifdef SIGSWAP
175f08c3bdfSopenharmony_ci		case SIGSWAP:
176f08c3bdfSopenharmony_ci#endif /* SIGSWAP */
177f08c3bdfSopenharmony_ci
178f08c3bdfSopenharmony_ci#ifdef SIGCKPT
179f08c3bdfSopenharmony_ci		case SIGCKPT:
180f08c3bdfSopenharmony_ci#endif
181f08c3bdfSopenharmony_ci#ifdef SIGRESTART
182f08c3bdfSopenharmony_ci		case SIGRESTART:
183f08c3bdfSopenharmony_ci#endif
184f08c3bdfSopenharmony_ci			/*
185f08c3bdfSopenharmony_ci			 * pthread-private signals SIGPTINTR and SIGPTRESCHED.
186f08c3bdfSopenharmony_ci			 * Setting a handler for these signals is disallowed when
187f08c3bdfSopenharmony_ci			 * the binary is linked against libpthread.
188f08c3bdfSopenharmony_ci			 */
189f08c3bdfSopenharmony_ci#ifdef SIGPTINTR
190f08c3bdfSopenharmony_ci		case SIGPTINTR:
191f08c3bdfSopenharmony_ci#endif /* SIGPTINTR */
192f08c3bdfSopenharmony_ci#ifdef SIGPTRESCHED
193f08c3bdfSopenharmony_ci		case SIGPTRESCHED:
194f08c3bdfSopenharmony_ci#endif /* SIGPTRESCHED */
195f08c3bdfSopenharmony_ci#ifdef _SIGRESERVE
196f08c3bdfSopenharmony_ci		case _SIGRESERVE:
197f08c3bdfSopenharmony_ci#endif
198f08c3bdfSopenharmony_ci#ifdef _SIGDIL
199f08c3bdfSopenharmony_ci		case _SIGDIL:
200f08c3bdfSopenharmony_ci#endif
201f08c3bdfSopenharmony_ci#ifdef _SIGCANCEL
202f08c3bdfSopenharmony_ci		case _SIGCANCEL:
203f08c3bdfSopenharmony_ci#endif
204f08c3bdfSopenharmony_ci#ifdef _SIGGFAULT
205f08c3bdfSopenharmony_ci		case _SIGGFAULT:
206f08c3bdfSopenharmony_ci#endif
207f08c3bdfSopenharmony_ci			break;
208f08c3bdfSopenharmony_ci
209f08c3bdfSopenharmony_ci		case SIGCHLD:
210f08c3bdfSopenharmony_ci			if (fork_flag == FORK)
211f08c3bdfSopenharmony_ci				continue;
212f08c3bdfSopenharmony_ci
213f08c3bdfSopenharmony_ci		default:
214f08c3bdfSopenharmony_ci			if (tst_setup_signal(sig, handler) == SIG_ERR)
215f08c3bdfSopenharmony_ci				tst_resm(TWARN | TERRNO,
216f08c3bdfSopenharmony_ci					 "signal failed for signal %d", sig);
217f08c3bdfSopenharmony_ci			break;
218f08c3bdfSopenharmony_ci		}
219f08c3bdfSopenharmony_ci	}
220f08c3bdfSopenharmony_ci}
221f08c3bdfSopenharmony_ci
222f08c3bdfSopenharmony_ci/****************************************************************************
223f08c3bdfSopenharmony_ci * def_handler() : default signal handler that is invoked when
224f08c3bdfSopenharmony_ci *      an unexpected signal is caught.
225f08c3bdfSopenharmony_ci ***************************************************************************/
226f08c3bdfSopenharmony_ci
227f08c3bdfSopenharmony_cistatic void def_handler(int sig)
228f08c3bdfSopenharmony_ci{
229f08c3bdfSopenharmony_ci	/*
230f08c3bdfSopenharmony_ci	 * Break remaining test cases, do any cleanup, then exit
231f08c3bdfSopenharmony_ci	 */
232f08c3bdfSopenharmony_ci	tst_brkm(TBROK, T_cleanup,
233f08c3bdfSopenharmony_ci		 "unexpected signal %s(%d) received (pid = %d).",
234f08c3bdfSopenharmony_ci		 tst_strsig(sig), sig, getpid());
235f08c3bdfSopenharmony_ci}
236f08c3bdfSopenharmony_ci
237f08c3bdfSopenharmony_ci/*
238f08c3bdfSopenharmony_ci * tst_setup_signal - A function like signal(), but we have
239f08c3bdfSopenharmony_ci *                    control over its personality.
240f08c3bdfSopenharmony_ci */
241f08c3bdfSopenharmony_cistatic void (*tst_setup_signal(int sig, void (*handler) (int))) (int) {
242f08c3bdfSopenharmony_ci	struct sigaction my_act, old_act;
243f08c3bdfSopenharmony_ci	int ret;
244f08c3bdfSopenharmony_ci
245f08c3bdfSopenharmony_ci	my_act.sa_handler = handler;
246f08c3bdfSopenharmony_ci	my_act.sa_flags = SA_RESTART;
247f08c3bdfSopenharmony_ci	sigemptyset(&my_act.sa_mask);
248f08c3bdfSopenharmony_ci
249f08c3bdfSopenharmony_ci	ret = sigaction(sig, &my_act, &old_act);
250f08c3bdfSopenharmony_ci
251f08c3bdfSopenharmony_ci	if (ret == 0)
252f08c3bdfSopenharmony_ci		return old_act.sa_handler;
253f08c3bdfSopenharmony_ci	else
254f08c3bdfSopenharmony_ci		return SIG_ERR;
255f08c3bdfSopenharmony_ci}
256