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
65void cleanup(void);
66void setup(void);
67void sighandler(int);
68
69char *TCID = "signal04";
70
71int 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
78int TST_TOTAL = sizeof(siglist) / sizeof(int);
79
80typedef void (*sighandler_t) (int);
81
82sighandler_t Tret;
83
84int 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 */
161void sighandler(int sig LTP_ATTRIBUTE_UNUSED)
162{
163}
164
165/*
166 * setup() - performs all the ONE TIME setup for this test.
167 */
168void 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 */
178void cleanup(void)
179{
180
181}
182