• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  * Test Name: sigsuspend01
22  *
23  * Test Description:
24  *  Verify that sigsuspend() succeeds to change process's current signal
25  *  mask with the specified signal mask and suspends the process execution
26  *  until the delivery of a signal.
27  *
28  * Expected Result:
29  *  sigsuspend() should return after the execution of signal catching
30  *  function and the previous signal mask should be restored.
31  *
32  * Algorithm:
33  *  Setup:
34  *   Setup signal handling.
35  *   Create temporary directory.
36  *   Pause for SIGUSR1 if option specified.
37  *
38  *  Test:
39  *   Loop if the proper options are given.
40  *   Execute system call
41  *   Check return code, if system call failed (return=-1)
42  *   	Log the errno and Issue a FAIL message.
43  *   Otherwise,
44  *   	Verify the Functionality of system call
45  *      if successful,
46  *      	Issue Functionality-Pass message.
47  *      Otherwise,
48  *		Issue Functionality-Fail message.
49  *  Cleanup:
50  *   Print errno log and/or timing stats if options given
51  *   Delete the temporary directory created.
52  *
53  * Usage:  <for command-line>
54  *  sigsuspend01 [-c n] [-e] [-f] [-i n] [-I x] [-p x] [-t]
55  *	where,  -c n : Run n copies concurrently.
56  *		-e   : Turn on errno logging.
57  *		-f   : Turn off functionality Testing.
58  *		-i n : Execute test n times.
59  *		-I x : Execute test for x seconds.
60  *		-P x : Pause for x seconds between iterations.
61  *		-t   : Turn on syscall timing.
62  *
63  * History
64  *	07/2001 John George
65  *		-Ported
66  *
67  * Restrictions:
68  *  None.
69  */
70 
71 #include <stdio.h>
72 #include <unistd.h>
73 #include <sys/types.h>
74 #include <errno.h>
75 #include <fcntl.h>
76 #include <string.h>
77 #include <signal.h>
78 #include <ucontext.h>
79 
80 #include "test.h"
81 
82 char *TCID = "sigsuspend01";
83 int TST_TOTAL = 1;
84 
85 struct sigaction sa_new;	/* struct to hold signal info */
86 sigset_t signalset;		/* signal set to hold signal lists */
87 sigset_t sigset1;
88 sigset_t sigset2;
89 
90 void setup();			/* Main setup function of test */
91 void cleanup();			/* cleanup function for the test */
92 void sig_handler(int sig);	/* signal catching function */
93 
main(int ac,char ** av)94 int main(int ac, char **av)
95 {
96 	int lc;
97 
98 	tst_parse_opts(ac, av, NULL, NULL);
99 
100 	setup();
101 
102 	for (lc = 0; TEST_LOOPING(lc); lc++) {
103 
104 		tst_count = 0;
105 
106 		/* Set the alarm timer */
107 		alarm(5);
108 
109 		/*
110 		 * Call sigsuspend() to replace current signal mask
111 		 * of the process and suspend process execution till
112 		 * receipt of a signal 'SIGALRM'.
113 		 */
114 		TEST(sigsuspend(&signalset));
115 
116 		/* Reset the alarm timer */
117 		alarm(0);
118 
119 		if ((TEST_RETURN == -1) && (TEST_ERRNO == EINTR)) {
120 			if (sigprocmask(SIG_UNBLOCK, 0, &sigset2) == -1) {
121 				tst_resm(TFAIL, "sigprocmask() Failed "
122 					 "to get previous signal mask "
123 					 "of process");
124 			} else if (memcmp(&sigset1, &sigset2,
125 				   sizeof(unsigned long))) {
126 				tst_resm(TFAIL, "sigsuspend failed to "
127 					 "preserve signal mask");
128 			} else {
129 				tst_resm(TPASS, "Functionality of "
130 					 "sigsuspend() successful");
131 			}
132 		} else {
133 			tst_resm(TFAIL | TTERRNO,
134 				 "sigsuspend() returned value %ld",
135 				 TEST_RETURN);
136 		}
137 
138 		tst_count++;	/* incr TEST_LOOP counter */
139 	}
140 
141 	cleanup();
142 	tst_exit();
143 }
144 
145 /*
146  * void
147  * setup() - performs all ONE TIME setup for this test.
148  * Initialise signal set with the list that includes/excludes
149  * all system-defined signals.
150  * Set the signal handler to catch SIGALRM signal.
151  * Get the current signal mask of test process using sigprocmask().
152  */
setup(void)153 void setup(void)
154 {
155 
156 	tst_sig(FORK, DEF_HANDLER, cleanup);
157 
158 	TEST_PAUSE;
159 
160 	/*
161 	 * Initialise the signal sets with the list that
162 	 * excludes/includes  all system-defined signals.
163 	 */
164 	if (sigemptyset(&signalset) == -1) {
165 		tst_brkm(TFAIL, cleanup,
166 			 "sigemptyset() failed, errno=%d : %s",
167 			 errno, strerror(errno));
168 	}
169 	if (sigfillset(&sigset2) == -1) {
170 		tst_brkm(TFAIL, cleanup,
171 			 "sigfillset() failed, errno=%d : %s",
172 			 errno, strerror(errno));
173 	}
174 
175 	/* Set the signal handler function to catch the signal */
176 	sa_new.sa_handler = sig_handler;
177 	if (sigaction(SIGALRM, &sa_new, 0) == -1) {
178 		tst_brkm(TFAIL, cleanup,
179 			 "sigaction() failed, errno=%d : %s",
180 			 errno, strerror(errno));
181 	}
182 
183 	/* Read the test process's current signal mask. */
184 	if (sigprocmask(SIG_UNBLOCK, 0, &sigset1) == -1) {
185 		tst_brkm(TFAIL, cleanup,
186 			 "sigprocmask() Failed, errno=%d : %s",
187 			 errno, strerror(errno));
188 	}
189 }
190 
191 /*
192  * void
193  * sig_handler(int sig) - Signal catching function.
194  *   This function gets executed when the signal SIGALRM is delivered
195  *   to the test process after the expiry of alarm time and the signal was
196  *   trapped by sigaction() to execute this function.
197  *
198  *   This function simply returns without doing anything.
199  */
sig_handler(int sig)200 void sig_handler(int sig)
201 {
202 }
203 
204 /*
205  * void
206  * cleanup() - performs all ONE TIME cleanup for this test at
207  *             completion or premature exit.
208  */
cleanup(void)209 void cleanup(void)
210 {
211 
212 }
213