/*
 *
 *   Copyright (c) International Business Machines  Corp., 2001
 *
 *   This program is free software;  you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation; either version 2 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
 *   the GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program;  if not, write to the Free Software
 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

/*
 * NAME
 * 	sigaction01.c
 *
 * DESCRIPTION
 * 	Test some features of sigaction (see below for more details)
 *
 * ALGORITHM
 * 	Use sigaction(2) to set a signal handler for SIGUSR1 with a certain
 * 	set of flags, set a global variable indicating the test case, and
 * 	finally send the signal to ourselves, causing the signal handler to
 * 	run. The signal handler then checks the signal handler to run. The
 * 	signal handler then checks certain conditions based on the test case
 * 	number.
 * 	There are 4 test cases:
 *
 * 	1) Set SA_RESETHAND and SA_SIGINFO. When the handler runs,
 * 	SA_SIGINFO should be set.
 *
 * 	2) Set SA_RESETHAND. When the handler runs, SIGUSR1 should be
 * 	masked (SA_RESETHAND makes sigaction behave as if SA_NODEFER was
 * 	not set).
 *
 * 	3) Same as case #2, but when the handler is established, sa_mask is
 * 	set to include SIGUSR1. Ensure that SIGUSR1 is indeed masked even if
 * 	SA_RESETHAND is set.
 *
 * 	4) A signal generated from an interface or condition that does not
 * 	provide siginfo (such as pthread_kill(3)) should invoke the handler
 * 	with a non-NULL siginfo pointer.
 *
 * USAGE:  <for command-line>
 * sigaction01 [-c n] [-f] [-i n] [-I x] [-P x] [-t]
 *     where,  -c n : Run n copies concurrently.
 *             -f   : Turn off functionality Testing.
 *             -i n : Execute test n times.
 *             -I x : Execute test for x seconds.
 *             -P x : Pause for x seconds between iterations.
 *             -t   : Turn on syscall timing.
 *
 * HISTORY
 *	07/2001 Ported by Wayne Boyer
 *
 * RESTRICTIONS
 *	NONE
 */
#include <pthread.h>
#include <signal.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include "test.h"

void setup();
void cleanup();

char *TCID = "sigaction01";
int TST_TOTAL = 4;

volatile sig_atomic_t testcase_no;
volatile sig_atomic_t pass;

/*
 * handler()
 *
 * 	A signal handler that understands which test case is currently
 * 	being executed and compares the current conditions to the ones it
 * 	expects (based on the test case number).
 */
void handler(int sig, siginfo_t * sip, void *ucp)
{
	struct sigaction oact;
	int err;
	sigset_t nmask, omask;

	/*
	 * Get sigaction setting
	 */
	err = sigaction(SIGUSR1, NULL, &oact);

	if (err == -1) {
		perror("sigaction");
		return;
	}

	/*
	 * Get current signal mask
	 */
	sigemptyset(&nmask);
	sigemptyset(&omask);
	err = sigprocmask(SIG_BLOCK, &nmask, &omask);
	if (err == -1) {
		perror("sigprocmask");
		tst_resm(TWARN, "sigprocmask() failed");
		return;
	}

	switch (testcase_no) {
	case 1:
		/*
		 * SA_RESETHAND and SA_SIGINFO were set. SA_SIGINFO should
		 * be clear in Linux. In Linux kernel, SA_SIGINFO is not
		 * cleared in psig().
		 */
		if (!(oact.sa_flags & SA_SIGINFO)) {
			tst_resm(TFAIL, "SA_RESETHAND should not "
				 "cause SA_SIGINFO to be cleared, but it was.");
			return;
		}
		if (sip == NULL) {
			tst_resm(TFAIL, "siginfo should not be NULL");
			return;
		}
		tst_resm(TPASS, "SA_RESETHAND did not "
			 "cause SA_SIGINFO to be cleared");
		break;

	case 2:
		/*
		 * In Linux, SA_RESETHAND doesn't imply SA_NODEFER; sig
		 * should not be masked.  The testcase should pass if
		 * SA_NODEFER is not masked, ie. if SA_NODEFER is a member
		 * of the signal list
		 */
		if (sigismember(&omask, sig) == 0) {
			tst_resm(TFAIL, "SA_RESETHAND should cause sig to"
				 "be masked when the handler executes.");
			return;
		}
		tst_resm(TPASS, "SA_RESETHAND was masked when handler "
			 "executed");
		break;

	case 3:
		/*
		 * SA_RESETHAND implies SA_NODEFER unless sa_mask already
		 * included sig.
		 */
		if (!sigismember(&omask, sig)) {
			tst_resm(TFAIL, "sig should continue to be masked"
				 "because sa_mask originally contained sig.");
			return;
		}
		tst_resm(TPASS, "sig has been masked "
			 "because sa_mask originally contained sig");
		break;

	case 4:
		/*
		 * A signal generated from a mechanism that does not provide
		 * siginfo should invoke the handler with a non-NULL siginfo
		 * pointer.
		 */
		if (sip == NULL) {
			tst_resm(TFAIL, "siginfo pointer should not be NULL");
			return;
		}
		tst_resm(TPASS, "siginfo pointer non NULL");
		break;

	default:
		tst_resm(TFAIL, "invalid test case number: %d", testcase_no);
		exit(1);
	}
}

/*
 * set_handler()
 *
 * 	Establish a signal handler for SIGUSR1 with the specified flags and
 * 	signal to mask while the handler executes.
 */
int set_handler(int flags, int sig_to_mask)
{
	struct sigaction sa;

	sa.sa_sigaction = handler;
	sa.sa_flags = flags;
	sigemptyset(&sa.sa_mask);
	sigaddset(&sa.sa_mask, sig_to_mask);

	TEST(sigaction(SIGUSR1, &sa, NULL));
	if (TEST_RETURN != 0) {
		perror("sigaction");
		tst_resm(TFAIL, "call failed unexpectedly");
		return 1;
	}
	return 0;
}

/*
 * setup() - performs all ONE TIME setup for this test.
 */
void setup(void)
{

	TEST_PAUSE;
}

/*
 * cleanup() - performs all ONE TIME cleanup for this test at
 *	       completion or premature exit.
 */
void cleanup(void)
{

}

int main(int ac, char **av)
{
	int lc;
	const char *msg;		/* message got from parse_opts */
	int i;
	int test_flags[] = { SA_RESETHAND | SA_SIGINFO, SA_RESETHAND,
		SA_RESETHAND | SA_SIGINFO, SA_RESETHAND | SA_SIGINFO
	};

	if ((msg = parse_opts(ac, av, NULL, NULL)) != NULL) {
		tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
	}

	setup();

	for (lc = 0; TEST_LOOPING(lc); lc++) {

		/* reset tst_count in case we are looping */
		tst_count = 0;

		testcase_no = 0;

		for (i = 0; i < TST_TOTAL; i++) {
			if (set_handler(test_flags[i], 0) == 0) {
				testcase_no++;
				switch (i) {
				case 0:
				 /*FALLTHROUGH*/ case 1:
					(void)kill(getpid(), SIGUSR1);
					break;
				case 2:
				 /*FALLTHROUGH*/ case 3:
					(void)
					    pthread_kill(pthread_self(),
							 SIGUSR1);
					break;
				default:
					tst_brkm(TBROK, cleanup,
						 "illegal case number");
					break;
				}
			}
		}
	}

	cleanup();
	tst_exit();
}
