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