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 sigset; /* 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(&sigset));
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 (sigset2.__val[0] != sigset1.__val[0]) {
125 tst_resm(TFAIL, "sigsuspend failed to "
126 "preserve signal mask");
127 } else {
128 tst_resm(TPASS, "Functionality of "
129 "sigsuspend() successful");
130 }
131 } else {
132 tst_resm(TFAIL | TTERRNO,
133 "sigsuspend() returned value %ld",
134 TEST_RETURN);
135 }
136
137 tst_count++; /* incr TEST_LOOP counter */
138 }
139
140 cleanup();
141 tst_exit();
142 }
143
144 /*
145 * void
146 * setup() - performs all ONE TIME setup for this test.
147 * Initialise signal set with the list that includes/excludes
148 * all system-defined signals.
149 * Set the signal handler to catch SIGALRM signal.
150 * Get the current signal mask of test process using sigprocmask().
151 */
setup(void)152 void setup(void)
153 {
154
155 tst_sig(FORK, DEF_HANDLER, cleanup);
156
157 TEST_PAUSE;
158
159 /*
160 * Initialise the signal sets with the list that
161 * excludes/includes all system-defined signals.
162 */
163 if (sigemptyset(&sigset) == -1) {
164 tst_brkm(TFAIL, cleanup,
165 "sigemptyset() failed, errno=%d : %s",
166 errno, strerror(errno));
167 }
168 if (sigfillset(&sigset2) == -1) {
169 tst_brkm(TFAIL, cleanup,
170 "sigfillset() failed, errno=%d : %s",
171 errno, strerror(errno));
172 }
173
174 /* Set the signal handler function to catch the signal */
175 sa_new.sa_handler = sig_handler;
176 if (sigaction(SIGALRM, &sa_new, 0) == -1) {
177 tst_brkm(TFAIL, cleanup,
178 "sigaction() failed, errno=%d : %s",
179 errno, strerror(errno));
180 }
181
182 /* Read the test process's current signal mask. */
183 if (sigprocmask(SIG_UNBLOCK, 0, &sigset1) == -1) {
184 tst_brkm(TFAIL, cleanup,
185 "sigprocmask() Failed, errno=%d : %s",
186 errno, strerror(errno));
187 }
188 }
189
190 /*
191 * void
192 * sig_handler(int sig) - Signal catching function.
193 * This function gets executed when the signal SIGALRM is delivered
194 * to the test process after the expiry of alarm time and the signal was
195 * trapped by sigaction() to execute this function.
196 *
197 * This function simply returns without doing anything.
198 */
sig_handler(int sig)199 void sig_handler(int sig)
200 {
201 }
202
203 /*
204 * void
205 * cleanup() - performs all ONE TIME cleanup for this test at
206 * completion or premature exit.
207 */
cleanup(void)208 void cleanup(void)
209 {
210
211 }
212