Skip to content

Commit 58be847

Browse files
yangx-jymetan-ucw
authored andcommitted
syscalls/sigsuspend01.c: Convert to the new API
Also add an extra check point: The process can unblock and receive SIGALRM by sigsuspend() even if sigprocmask() has blocked SIGALRM. Signed-off-by: Xiao Yang <[email protected]> Signed-off-by: Cyril Hrubis <[email protected]> Reviewed-by: Cyril Hrubis <[email protected]>
1 parent 76c1fe2 commit 58be847

File tree

1 file changed

+54
-184
lines changed

1 file changed

+54
-184
lines changed
Lines changed: 54 additions & 184 deletions
Original file line numberDiff line numberDiff line change
@@ -1,212 +1,82 @@
1+
// SPDX-License-Identifier: GPL-2.0-or-later
12
/*
3+
* Copyright (c) International Business Machines Corp., 2001
24
*
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
5+
* Description:
6+
* Verify the basic function of sigsuspend():
7+
* 1) sigsuspend() can replace process's current signal mask
8+
* by the specified signal mask and suspend the process
9+
* execution until the delivery of a signal.
10+
* 2) sigsuspend() should return after the execution of signal
11+
* handler and restore the previous signal mask.
1812
*/
1913

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>
7414
#include <errno.h>
75-
#include <fcntl.h>
15+
#include <unistd.h>
7616
#include <string.h>
7717
#include <signal.h>
78-
#include <ucontext.h>
79-
80-
#include "test.h"
81-
82-
char *TCID = "sigsuspend01";
83-
int TST_TOTAL = 1;
8418

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;
19+
#include "tst_test.h"
8920

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 */
21+
static sigset_t signalset, sigset1, sigset2;
22+
static volatile sig_atomic_t alarm_num;
9323

94-
int main(int ac, char **av)
24+
static void sig_handler(int sig)
9525
{
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();
26+
alarm_num = sig;
14327
}
14428

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-
*/
153-
void setup(void)
29+
static void verify_sigsuspend(void)
15430
{
31+
alarm_num = 0;
15532

156-
tst_sig(FORK, DEF_HANDLER, cleanup);
33+
SAFE_SIGFILLSET(&sigset2);
15734

158-
TEST_PAUSE;
35+
alarm(1);
15936

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));
37+
/* Unblock SIGALRM */
38+
TEST(sigsuspend(&signalset));
39+
40+
alarm(0);
41+
42+
if (TST_RET != -1 || TST_ERR != EINTR) {
43+
tst_res(TFAIL | TTERRNO,
44+
"sigsuspend() returned value %ld", TST_RET);
45+
return;
17346
}
17447

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));
48+
if (alarm_num != SIGALRM) {
49+
tst_res(TFAIL, "sigsuspend() didn't unblock SIGALRM");
50+
return;
18151
}
18252

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));
53+
SAFE_SIGPROCMASK(0, NULL, &sigset2);
54+
if (memcmp(&sigset1, &sigset2, sizeof(unsigned long))) {
55+
tst_res(TFAIL, "sigsuspend() failed to "
56+
"restore the previous signal mask");
57+
return;
18858
}
189-
}
19059

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-
*/
200-
void sig_handler(int sig)
201-
{
60+
tst_res(TPASS, "sigsuspend() succeeded");
20261
}
20362

204-
/*
205-
* void
206-
* cleanup() - performs all ONE TIME cleanup for this test at
207-
* completion or premature exit.
208-
*/
209-
void cleanup(void)
63+
static void setup(void)
21064
{
65+
SAFE_SIGEMPTYSET(&signalset);
66+
SAFE_SIGEMPTYSET(&sigset1);
67+
SAFE_SIGADDSET(&sigset1, SIGALRM);
68+
69+
struct sigaction sa_new = {
70+
.sa_handler = sig_handler,
71+
};
21172

73+
SAFE_SIGACTION(SIGALRM, &sa_new, 0);
74+
75+
/* Block SIGALRM */
76+
SAFE_SIGPROCMASK(SIG_SETMASK, &sigset1, NULL);
21277
}
78+
79+
static struct tst_test test = {
80+
.setup = setup,
81+
.test_all = verify_sigsuspend,
82+
};

0 commit comments

Comments
 (0)