1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Copyright (c) 2016 Fujitsu Ltd.
4 * Author: Guangwen Feng <fenggw-fnst@cn.fujitsu.com>
5 * Copyright (c) 2021 Xie Ziyao <xieziyao@huawei.com>
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(1, 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
epoll_pwait_support(void)76 static void epoll_pwait_support(void)
77 {
78 if (tst_variant == 0)
79 epoll_pwait_supported();
80 else
81 epoll_pwait2_supported();
82 }
83
setup(void)84 static void setup(void)
85 {
86 SAFE_SIGEMPTYSET(&signalset);
87 SAFE_SIGADDSET(&signalset, SIGUSR1);
88
89 sa.sa_flags = 0;
90 sa.sa_handler = sighandler;
91 SAFE_SIGEMPTYSET(&sa.sa_mask);
92 SAFE_SIGACTION(SIGUSR1, &sa, NULL);
93
94 epoll_pwait_info();
95 epoll_pwait_support();
96
97 SAFE_SOCKETPAIR(AF_UNIX, SOCK_STREAM, 0, sfd);
98
99 efd = epoll_create(1);
100 if (efd == -1)
101 tst_brk(TBROK | TERRNO, "epoll_create()");
102
103 e.events = EPOLLIN;
104 if (epoll_ctl(efd, EPOLL_CTL_ADD, sfd[0], &e))
105 tst_brk(TBROK | TERRNO, "epoll_clt(..., EPOLL_CTL_ADD, ...)");
106 }
107
cleanup(void)108 static void cleanup(void)
109 {
110 if (efd > 0)
111 SAFE_CLOSE(efd);
112
113 if (sfd[0] > 0)
114 SAFE_CLOSE(sfd[0]);
115
116 if (sfd[1] > 0)
117 SAFE_CLOSE(sfd[1]);
118 }
119
120 static struct tst_test test = {
121 .test = run,
122 .setup = setup,
123 .cleanup = cleanup,
124 .forks_child = 1,
125 .test_variants = TEST_VARIANTS,
126 .tcnt = ARRAY_SIZE(testcase_list),
127 };
128