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