Home | History | Annotate | Download | only in signal
      1 /*
      2  *
      3  *   Copyright (c) International Business Machines  Corp., 2001
      4  *
      5  *   This program is free software;  you can redistribute it and/or modify
      6  *   it under the terms of the GNU General Public License as published by
      7  *   the Free Software Foundation; either version 2 of the License, or
      8  *   (at your option) any later version.
      9  *
     10  *   This program is distributed in the hope that it will be useful,
     11  *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
     12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
     13  *   the GNU General Public License for more details.
     14  *
     15  *   You should have received a copy of the GNU General Public License
     16  *   along with this program;  if not, write to the Free Software
     17  *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
     18  */
     19 
     20 /*
     21  * NAME
     22  *	signal04.c
     23  *
     24  * DESCRIPTION
     25  *	signal04 - restore signals to default behavior
     26  *
     27  * ALGORITHM
     28  *	loop if that option was specified
     29  *	for each signal in siglist[]
     30  *	  set the signal handler to our own and save the return value
     31  *	  issue the signal system call to restore the default behavior
     32  *	  check the return value
     33  *	  if return value == -1
     34  *	    issue a FAIL message, break remaining tests and cleanup
     35  *	  if we are doing functional testing
     36  *	    set the signal handler to our own again and save second return value
     37  *	    if the first return value matches the second return value
     38  *	      issue a PASS message
     39  *	    else
     40  *	      issue a FAIL message
     41  *	call cleanup
     42  *
     43  * USAGE:  <for command-line>
     44  *  signal04 [-c n] [-f] [-i n] [-I x] [-p x] [-t]
     45  *	where,  -c n : Run n copies concurrently.
     46  *		-f   : Turn off functionality Testing.
     47  *		-i n : Execute test n times.
     48  *		-I x : Execute test for x seconds.
     49  *		-P x : Pause for x seconds between iterations.
     50  *		-t   : Turn on syscall timing.
     51  *
     52  * History
     53  *	07/2001 John George
     54  *		-Ported
     55  *
     56  * Restrictions
     57  *	none
     58  */
     59 
     60 #include "test.h"
     61 
     62 #include <errno.h>
     63 #include <signal.h>
     64 
     65 void cleanup(void);
     66 void setup(void);
     67 void sighandler(int);
     68 
     69 char *TCID = "signal04";
     70 
     71 int siglist[] = { SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGTRAP, SIGABRT,
     72 	SIGBUS, SIGFPE, SIGUSR1, SIGSEGV, SIGUSR2, SIGPIPE, SIGALRM,
     73 	SIGTERM, SIGCHLD, SIGCONT, SIGTSTP, SIGTTIN,
     74 	SIGTTOU, SIGURG, SIGXCPU, SIGXFSZ, SIGVTALRM, SIGPROF,
     75 	SIGWINCH, SIGIO, SIGPWR, SIGSYS
     76 };
     77 
     78 int TST_TOTAL = sizeof(siglist) / sizeof(int);
     79 
     80 typedef void (*sighandler_t) (int);
     81 
     82 sighandler_t Tret;
     83 
     84 int main(int ac, char **av)
     85 {
     86 	int lc;
     87 	int i;
     88 	sighandler_t rval, first;
     89 
     90 	tst_parse_opts(ac, av, NULL, NULL);
     91 
     92 	setup();		/* global setup */
     93 
     94 	/* The following loop checks looping state if -i option given */
     95 
     96 	for (lc = 0; TEST_LOOPING(lc); lc++) {
     97 		/* reset tst_count in case we are looping */
     98 		tst_count = 0;
     99 
    100 		/*
    101 		 * loop through the list of signals and test each one
    102 		 */
    103 		for (i = 0; i < TST_TOTAL; i++) {
    104 
    105 			/* First reset the signal to the default
    106 			   action to clear out any pre-test
    107 			   execution settings */
    108 			signal(siglist[i], SIG_DFL);
    109 
    110 			/* then set the handler to our own handler */
    111 			if ((rval = signal(siglist[i], &sighandler)) == SIG_ERR) {
    112 				tst_brkm(TBROK, cleanup, "initial signal call"
    113 					 " failed");
    114 			}
    115 
    116 			/* store the return value */
    117 			first = rval;
    118 
    119 			/* restore the default signal action */
    120 			errno = 0;
    121 			Tret = signal(siglist[i], SIG_DFL);
    122 			TEST_ERRNO = errno;
    123 
    124 			if (Tret == SIG_ERR) {
    125 				tst_brkm(TFAIL, cleanup, "%s call failed - "
    126 					 "errno = %d : %s", TCID, TEST_ERRNO,
    127 					 strerror(TEST_ERRNO));
    128 			}
    129 
    130 			/* now set the handler back to our own */
    131 			if ((rval = signal(siglist[i], &sighandler))
    132 			    == SIG_ERR) {
    133 				tst_brkm(TBROK, cleanup, "initial "
    134 					 "signal call failed");
    135 			}
    136 
    137 			/*
    138 			 * the first return value should equal the
    139 			 * second one.
    140 			 */
    141 			if (rval == first) {
    142 				tst_resm(TPASS, "%s call succeeded "
    143 					 "received %p.", TCID, rval);
    144 			} else {
    145 				tst_brkm(TFAIL, cleanup, "return "
    146 					 "values for signal(%d) don't "
    147 					 "match. Got %p, expected %p.",
    148 					 siglist[i], rval, first);
    149 			}
    150 		}
    151 	}
    152 
    153 	cleanup();
    154 	tst_exit();
    155 
    156 }
    157 
    158 /*
    159  * sighandler() - handle the signals
    160  */
    161 void sighandler(int sig LTP_ATTRIBUTE_UNUSED)
    162 {
    163 }
    164 
    165 /*
    166  * setup() - performs all the ONE TIME setup for this test.
    167  */
    168 void setup(void)
    169 {
    170 
    171 	TEST_PAUSE;
    172 }
    173 
    174 /*
    175  * cleanup() - performs all the ONE TIME cleanup for this test at completion
    176  * 	       or premature exit.
    177  */
    178 void cleanup(void)
    179 {
    180 
    181 }
    182