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