1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Copyright (c) 2016 Fujitsu Ltd.
4 * Author: Xiao Yang <yangx.jy@cn.fujitsu.com>
5 */
6
7 /*
8 * Test Name: epoll_ctl02.c
9 *
10 * Description:
11 * 1) epoll_ctl(2) fails if epfd is a invalid file descriptor.
12 * 2) epoll_ctl(2) fails if fd is a invalid file descriptor.
13 * 3) epoll_ctl(2) fails if op is not supported by this interface.
14 * 4) epoll_ctl(2) fails if fd is the same as epfd.
15 * 5) epoll_ctl(2) fails with EPOLL_CTL_DEL if fd is not registered
16 * with this epoll instance.
17 * 6) epoll_ctl(2) fails with EPOLL_CTL_MOD if fd is not registered
18 * with this epoll instance.
19 * 7) epoll_ctl(2) fails with EPOLL_CTL_ADD if fd is already registered
20 * with this epoll instance.
21 *
22 * Expected Result:
23 * 1) epoll_ctl(2) should return -1 and set errno to EBADF.
24 * 2) epoll_ctl(2) should return -1 and set errno to EBADF.
25 * 3) epoll_ctl(2) should return -1 and set errno to EINVAL.
26 * 4) epoll_ctl(2) should return -1 and set errno to EINVAL.
27 * 5) epoll_ctl(2) should return -1 and set errno to ENOENT.
28 * 6) epoll_ctl(2) should return -1 and set errno to ENOENT.
29 * 7) epoll_ctl(2) should return -1 and set errno to EEXIST.
30 *
31 */
32 #include <sys/epoll.h>
33 #include <poll.h>
34 #include <errno.h>
35 #include "tst_test.h"
36
37 static int epfd;
38 static int fd[2];
39 static int inv = -1;
40
41 static struct epoll_event events[2] = {
42 {.events = EPOLLIN},
43 {.events = EPOLLOUT},
44 };
45
46 static struct testcase {
47 int *epfds;
48 int opt;
49 int *fds;
50 struct epoll_event *ts_event;
51 int exp_err;
52 } tcases[] = {
53 {&inv, EPOLL_CTL_ADD, &fd[1], &events[1], EBADF},
54 {&epfd, EPOLL_CTL_ADD, &inv, &events[1], EBADF},
55 {&epfd, -1, &fd[1], &events[1], EINVAL},
56 {&epfd, EPOLL_CTL_ADD, &epfd, &events[1], EINVAL},
57 {&epfd, EPOLL_CTL_DEL, &fd[1], &events[1], ENOENT},
58 {&epfd, EPOLL_CTL_MOD, &fd[1], &events[1], ENOENT},
59 {&epfd, EPOLL_CTL_ADD, &fd[0], &events[0], EEXIST}
60 };
61
setup(void)62 static void setup(void)
63 {
64 epfd = epoll_create(2);
65 if (epfd == -1)
66 tst_brk(TBROK | TERRNO, "fail to create epoll instance");
67
68 SAFE_PIPE(fd);
69
70 events[0].data.fd = fd[0];
71 events[1].data.fd = fd[1];
72
73 TEST(epoll_ctl(epfd, EPOLL_CTL_ADD, fd[0], &events[0]));
74 if (TST_RET == -1)
75 tst_brk(TFAIL | TTERRNO, "epoll_ctl() fails to init");
76 }
77
cleanup(void)78 static void cleanup(void)
79 {
80 if (epfd)
81 SAFE_CLOSE(epfd);
82
83 if (fd[0])
84 SAFE_CLOSE(fd[0]);
85
86 if (fd[1])
87 SAFE_CLOSE(fd[1]);
88 }
89
verify_epoll_ctl(unsigned int n)90 static void verify_epoll_ctl(unsigned int n)
91 {
92 struct testcase *tc = &tcases[n];
93
94 TEST(epoll_ctl(*tc->epfds, tc->opt, *tc->fds, tc->ts_event));
95 if (TST_RET != -1) {
96 tst_res(TFAIL, "epoll_ctl() succeeds unexpectedly");
97 return;
98 }
99
100 if (tc->exp_err == TST_ERR) {
101 tst_res(TPASS | TTERRNO, "epoll_ctl() fails as expected");
102 } else {
103 tst_res(TFAIL | TTERRNO,
104 "epoll_ctl() fails unexpectedly, expected %i: %s",
105 tc->exp_err, tst_strerrno(tc->exp_err));
106 }
107 }
108
109 static struct tst_test test = {
110 .tcnt = ARRAY_SIZE(tcases),
111 .setup = setup,
112 .cleanup = cleanup,
113 .test = verify_epoll_ctl,
114 };
115