1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Copyright (c) 2016 Fujitsu Ltd.
4 * Author: Guangwen Feng <[email protected]>
5 * Copyright (c) 2021 Xie Ziyao <[email protected]>
6 */
7
8 /*\
9 * [Description]
10 *
11 * Basic test for epoll_pwait() and epoll_pwait2().
12 *
13 * - With a sigmask a signal is ignored and the syscall safely waits until
14 * either a file descriptor becomes ready or the timeout expires.
15 *
16 * - Without sigmask if signal arrives a syscall is iterrupted by a signal.
17 * The call should return -1 and set errno to EINTR.
18 */
19
20 #include <stdlib.h>
21 #include <sys/epoll.h>
22
23 #include "tst_test.h"
24 #include "epoll_pwait_var.h"
25
26 static int efd, sfd[2];
27 static struct epoll_event e;
28 static sigset_t signalset;
29 static struct sigaction sa;
30
sighandler(int sig LTP_ATTRIBUTE_UNUSED)31 static void sighandler(int sig LTP_ATTRIBUTE_UNUSED) {}
32
verify_sigmask(void)33 static void verify_sigmask(void)
34 {
35 TEST(do_epoll_pwait(efd, &e, 1, -1, &signalset));
36
37 if (TST_RET != 1) {
38 tst_res(TFAIL, "do_epoll_pwait() returned %li, expected 1",
39 TST_RET);
40 return;
41 }
42
43 tst_res(TPASS, "do_epoll_pwait() with sigmask blocked signal");
44 }
45
verify_nonsigmask(void)46 static void verify_nonsigmask(void)
47 {
48 TST_EXP_FAIL(do_epoll_pwait(efd, &e, 1, -1, NULL), EINTR,
49 "do_epoll_pwait() without sigmask");
50 }
51
52 static void (*testcase_list[])(void) = {verify_sigmask, verify_nonsigmask};
53
run(unsigned int n)54 static void run(unsigned int n)
55 {
56 char b;
57 pid_t pid;
58
59 if (!SAFE_FORK()) {
60 pid = getppid();
61
62 TST_PROCESS_STATE_WAIT(pid, 'S', 0);
63 SAFE_KILL(pid, SIGUSR1);
64
65 usleep(10000);
66 SAFE_WRITE(SAFE_WRITE_ALL, sfd[1], "w", 1);
67 exit(0);
68 }
69
70 testcase_list[n]();
71
72 SAFE_READ(1, sfd[0], &b, 1);
73 tst_reap_children();
74 }
75
setup(void)76 static void setup(void)
77 {
78 epoll_pwait_init();
79
80 SAFE_SIGEMPTYSET(&signalset);
81 SAFE_SIGADDSET(&signalset, SIGUSR1);
82
83 sa.sa_flags = 0;
84 sa.sa_handler = sighandler;
85 SAFE_SIGEMPTYSET(&sa.sa_mask);
86 SAFE_SIGACTION(SIGUSR1, &sa, NULL);
87
88 SAFE_SOCKETPAIR(AF_UNIX, SOCK_STREAM, 0, sfd);
89
90 efd = epoll_create(1);
91 if (efd == -1)
92 tst_brk(TBROK | TERRNO, "epoll_create()");
93
94 e.events = EPOLLIN;
95 if (epoll_ctl(efd, EPOLL_CTL_ADD, sfd[0], &e))
96 tst_brk(TBROK | TERRNO, "epoll_ctl(..., EPOLL_CTL_ADD, ...)");
97 }
98
cleanup(void)99 static void cleanup(void)
100 {
101 if (efd > 0)
102 SAFE_CLOSE(efd);
103
104 if (sfd[0] > 0)
105 SAFE_CLOSE(sfd[0]);
106
107 if (sfd[1] > 0)
108 SAFE_CLOSE(sfd[1]);
109 }
110
111 static struct tst_test test = {
112 .test = run,
113 .setup = setup,
114 .cleanup = cleanup,
115 .forks_child = 1,
116 .test_variants = TEST_VARIANTS,
117 .tcnt = ARRAY_SIZE(testcase_list),
118 };
119