/*
 * Copyright (c) 2000 Silicon Graphics, Inc.  All Rights Reserved.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of version 2 of the GNU General Public License as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it would be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 *
 * Further, this software is distributed without any warranty that it is
 * free of the rightful claim of any third person regarding infringement
 * or the like.  Any license provided herein, whether implied or
 * otherwise, applies only to this software file.  Patent licenses, if
 * any, provided herein do not apply to combinations of this program with
 * other software, or any other product whatsoever.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
 * Mountain View, CA  94043, or:
 *
 * http://www.sgi.com
 *
 * For further information regarding this notice, see:
 *
 * http://oss.sgi.com/projects/GenInfo/NoticeExplan/
 */

/* $Id: tst_sig.c,v 1.13 2009/08/28 09:29:01 vapier Exp $ */

/*****************************************************************************
	OS Testing  - Silicon Graphics, Inc.

	FUNCTION IDENTIFIER : tst_sig  Set up for unexpected signals.

	AUTHOR          : David D. Fenner

	CO-PILOT        : Bill Roske

	DATE STARTED    : 06/06/90

	This module may be linked with c-modules requiring unexpected
	signal handling.  The parameters to tst_sig are as follows:

		fork_flag - set to FORK or NOFORK depending upon whether the
			calling program executes a fork() system call.  It
			is normally the case that the calling program treats
			SIGCLD as an expected signal if fork() is being used.

		handler - a pointer to the unexpected signal handler to
			be executed after an unexpected signal has been
			detected.  If handler is set to DEF_HANDLER, a
			default handler is used.  This routine should be
			declared as function returning an int.

		cleanup - a pointer to a cleanup routine to be executed
			by the unexpected signal handler before tst_exit is
			called.  This parameter is set to NULL if no cleanup
			routine is required.  An external variable, T_cleanup
			is set so that other user-defined handlers have
			access to the cleanup routine.  This routine should be
			declared as returning type void.

***************************************************************************/

#include <errno.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>
#include "test.h"

#define MAXMESG 150		/* size of mesg string sent to tst_res */

void (*T_cleanup) ();		/* pointer to cleanup function */

/****************************************************************************
 * STD_COPIES is defined in parse_opts.c but is externed here in order to
 * test whether SIGCHILD should be ignored or not.
 ***************************************************************************/
extern int STD_COPIES;

static void def_handler();	/* default signal handler */
static void (*tst_setup_signal(int, void (*)(int))) (int);

/****************************************************************************
 * tst_sig() : set-up to catch unexpected signals.  fork_flag is set to NOFORK
 *    if SIGCLD is to be an "unexpected signal", otherwise it is set to
 *    FORK.  cleanup points to a cleanup routine to be executed before
 *    tst_exit is called (cleanup is set to NULL if no cleanup is desired).
 *    handler is a pointer to the signal handling routine (if handler is
 *    set to NULL, a default handler is used).
 ***************************************************************************/

void tst_sig(int fork_flag, void (*handler) (), void (*cleanup) ())
{
	int sig;
#ifdef _SC_SIGRT_MIN
	long sigrtmin, sigrtmax;
#endif

	/*
	 * save T_cleanup and handler function pointers
	 */
	T_cleanup = cleanup;	/* used by default handler */

	if (handler == DEF_HANDLER) {
		/* use default handler */
		handler = def_handler;
	}
#ifdef _SC_SIGRT_MIN
	sigrtmin = sysconf(_SC_SIGRT_MIN);
	sigrtmax = sysconf(_SC_SIGRT_MAX);
#endif

	/*
	 * now loop through all signals and set the handlers
	 */

	for (sig = 1; sig < NSIG; sig++) {
		/*
		 * SIGKILL is never unexpected.
		 * SIGCLD is only unexpected when
		 *    no forking is being done.
		 * SIGINFO is used for file quotas and should be expected
		 */

#ifdef _SC_SIGRT_MIN
		if (sig >= sigrtmin && sig <= sigrtmax)
			continue;
#endif

		switch (sig) {
		case SIGKILL:
		case SIGSTOP:
		case SIGCONT:
#if !defined(_SC_SIGRT_MIN) && defined(__SIGRTMIN) && defined(__SIGRTMAX)
			/* Ignore all real-time signals */
		case __SIGRTMIN:
		case __SIGRTMIN + 1:
		case __SIGRTMIN + 2:
		case __SIGRTMIN + 3:
		case __SIGRTMIN + 4:
		case __SIGRTMIN + 5:
		case __SIGRTMIN + 6:
		case __SIGRTMIN + 7:
		case __SIGRTMIN + 8:
		case __SIGRTMIN + 9:
		case __SIGRTMIN + 10:
		case __SIGRTMIN + 11:
		case __SIGRTMIN + 12:
		case __SIGRTMIN + 13:
		case __SIGRTMIN + 14:
		case __SIGRTMIN + 15:
/* __SIGRTMIN is 37 on HPPA rather than 32 *
 * as on i386, etc.                        */
#if !defined(__hppa__)
		case __SIGRTMAX - 15:
		case __SIGRTMAX - 14:
		case __SIGRTMAX - 13:
		case __SIGRTMAX - 12:
		case __SIGRTMAX - 11:
#endif
		case __SIGRTMAX - 10:
		case __SIGRTMAX - 9:
		case __SIGRTMAX - 8:
		case __SIGRTMAX - 7:
		case __SIGRTMAX - 6:
		case __SIGRTMAX - 5:
		case __SIGRTMAX - 4:
		case __SIGRTMAX - 3:
		case __SIGRTMAX - 2:
		case __SIGRTMAX - 1:
		case __SIGRTMAX:
#endif
#ifdef CRAY
		case SIGINFO:
		case SIGRECOVERY:	/* allow chkpnt/restart */
#endif /* CRAY */

#ifdef SIGSWAP
		case SIGSWAP:
#endif /* SIGSWAP */

#ifdef SIGCKPT
		case SIGCKPT:
#endif
#ifdef SIGRESTART
		case SIGRESTART:
#endif
			/*
			 * pthread-private signals SIGPTINTR and SIGPTRESCHED.
			 * Setting a handler for these signals is disallowed when
			 * the binary is linked against libpthread.
			 */
#ifdef SIGPTINTR
		case SIGPTINTR:
#endif /* SIGPTINTR */
#ifdef SIGPTRESCHED
		case SIGPTRESCHED:
#endif /* SIGPTRESCHED */
#ifdef _SIGRESERVE
		case _SIGRESERVE:
#endif
#ifdef _SIGDIL
		case _SIGDIL:
#endif
#ifdef _SIGCANCEL
		case _SIGCANCEL:
#endif
#ifdef _SIGGFAULT
		case _SIGGFAULT:
#endif
			break;

		case SIGCLD:
			if (fork_flag == FORK || STD_COPIES > 1)
				continue;

		default:
			if (tst_setup_signal(sig, handler) == SIG_ERR)
				tst_resm(TWARN | TERRNO,
					 "signal failed for signal %d", sig);
			break;
		}
#ifdef __sgi
		/* On irix  (07/96), signal() fails when signo is 33 or higher */
		if (sig + 1 >= 33)
			break;
#endif /*  __sgi */

	}			/* endfor */
}

/****************************************************************************
 * def_handler() : default signal handler that is invoked when
 *      an unexpected signal is caught.
 ***************************************************************************/

static void def_handler(int sig)
{
	/*
	 * Break remaining test cases, do any cleanup, then exit
	 */
	tst_brkm(TBROK, T_cleanup,
		 "unexpected signal %d received (pid = %d).", sig, getpid());
}

/*
 * tst_setup_signal - A function like signal(), but we have
 *                    control over its personality.
 */
static void (*tst_setup_signal(int sig, void (*handler) (int))) (int) {
	struct sigaction my_act, old_act;
	int ret;

	my_act.sa_handler = handler;
	my_act.sa_flags = SA_RESTART;
	sigemptyset(&my_act.sa_mask);

	ret = sigaction(sig, &my_act, &old_act);

	if (ret == 0)
		return old_act.sa_handler;
	else
		return SIG_ERR;
}
