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  *	signal05.c
     23  *
     24  * DESCRIPTION
     25  *	signal05 - set the signal handler to our own function
     26  *
     27  * ALGORITHM
     28  *	loop if that option was specified
     29  *	issue the system call
     30  *	check the return value
     31  *	  if return value == -1
     32  *	    issue a FAIL message, break remaining tests and cleanup
     33  *	  if we are doing functional testing
     34  *	    send the signal with kill()
     35  *	    if we catch the signal in the signal handler
     36  *	      issue a PASS message
     37  *	    else
     38  *	      issue a FAIL message
     39  *	call cleanup
     40  *
     41  * USAGE:  <for command-line>
     42  *  signal05 [-c n] [-f] [-i n] [-I x] [-p x] [-t]
     43  *     where,  -c n : Run n copies concurrently.
     44  *             -f   : Turn off functionality Testing.
     45  *	       -i n : Execute test n times.
     46  *	       -I x : Execute test for x seconds.
     47  *	       -P x : Pause for x seconds between iterations.
     48  *	       -t   : Turn on syscall timing.
     49  *
     50  * History
     51  *	07/2001 John George
     52  *		-Ported
     53  *
     54  * Restrictions
     55  *	none
     56  */
     57 
     58 #include "test.h"
     59 
     60 #include <errno.h>
     61 #include <signal.h>
     62 
     63 void cleanup(void);
     64 void setup(void);
     65 void sighandler(int);
     66 
     67 int siglist[] = { SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGTRAP, SIGABRT, SIGIOT,
     68 	SIGBUS, SIGFPE, SIGUSR1, SIGSEGV, SIGUSR2, SIGPIPE, SIGALRM,
     69 	SIGTERM,
     70 #ifdef SIGSTKFLT
     71 	SIGSTKFLT,
     72 #endif
     73 	SIGCHLD, SIGCONT, SIGTSTP, SIGTTIN,
     74 	SIGTTOU, SIGURG, SIGXCPU, SIGXFSZ, SIGVTALRM, SIGPROF,
     75 	SIGWINCH, SIGIO, SIGPWR, SIGSYS,
     76 #ifdef SIGUNUSED
     77 	SIGUNUSED
     78 #endif
     79 };
     80 
     81 char *TCID = "signal05";
     82 int TST_TOTAL = ARRAY_SIZE(siglist);
     83 
     84 typedef void (*sighandler_t) (int);
     85 
     86 sighandler_t Tret;
     87 
     88 int pass = 0;
     89 
     90 int main(int ac, char **av)
     91 {
     92 	int lc;
     93 	pid_t pid;
     94 	int i, rval;
     95 
     96 	tst_parse_opts(ac, av, NULL, NULL);
     97 
     98 	setup();		/* global setup */
     99 
    100 	/* The following loop checks looping state if -i option given */
    101 
    102 	for (lc = 0; TEST_LOOPING(lc); lc++) {
    103 		/* reset tst_count in case we are looping */
    104 		tst_count = 0;
    105 
    106 		/*
    107 		 * loop through the list of signals and test each one
    108 		 */
    109 		for (i = 0; i < TST_TOTAL; i++) {
    110 
    111 			errno = 0;
    112 			Tret = signal(siglist[i], &sighandler);
    113 			TEST_ERRNO = errno;
    114 
    115 			if (Tret == SIG_ERR) {
    116 				tst_resm(TFAIL, "%s call failed - errno = %d "
    117 					 ": %s", TCID, TEST_ERRNO,
    118 					 strerror(TEST_ERRNO));
    119 				continue;
    120 			}
    121 
    122 			/*
    123 			 * Send the signals and make sure they are
    124 			 * handled in our handler.
    125 			 */
    126 			pid = getpid();
    127 
    128 			if ((rval = kill(pid, siglist[i])) != 0) {
    129 				tst_brkm(TBROK, cleanup,
    130 					 "call to kill failed");
    131 			}
    132 
    133 			if (siglist[i] == pass) {
    134 				tst_resm(TPASS,
    135 					 "%s call succeeded", TCID);
    136 			} else {
    137 				tst_resm(TFAIL,
    138 					 "received unexpected signal");
    139 			}
    140 		}
    141 	}
    142 
    143 	cleanup();
    144 	tst_exit();
    145 }
    146 
    147 /*
    148  * sighandler() - handle the signals
    149  */
    150 void sighandler(int sig)
    151 {
    152 	/* set the global pass variable = sig */
    153 	pass = sig;
    154 }
    155 
    156 /*
    157  * setup() - performs all the ONE TIME setup for this test.
    158  */
    159 void setup(void)
    160 {
    161 	TEST_PAUSE;
    162 }
    163 
    164 /*
    165  * cleanup() - performs all the ONE TIME cleanup for this test at completion
    166  * 	       or premature exit.
    167  */
    168 void cleanup(void)
    169 {
    170 
    171 }
    172