1 /* 2 * Copyright (c) 2016 Fujitsu Ltd. 3 * Author: Guangwen Feng <fenggw-fnst@cn.fujitsu.com> 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. 17 */ 18 19 /* 20 * Description: 21 * 1) epoll_wait(2) fails if epfd is not a valid file descriptor 22 * 2) epoll_wait(2) fails if epfd is not an epoll file descriptor 23 * 3) epoll_wait(2) fails if maxevents is less than zero 24 * 4) epoll_wait(2) fails if maxevents is equal to zero 25 * 5) epoll_wait(2) fails if the memory area pointed to by events 26 * is not accessible with write permissions. 27 * 28 * Expected Result: 29 * 1) epoll_wait(2) should return -1 and set errno to EBADF 30 * 2) epoll_wait(2) should return -1 and set errno to EINVAL 31 * 3) epoll_wait(2) should return -1 and set errno to EINVAL 32 * 4) epoll_wait(2) should return -1 and set errno to EINVAL 33 * 5) epoll_wait(2) should return -1 and set errno to EFAULT 34 */ 35 36 #include <sys/epoll.h> 37 #include <sys/mman.h> 38 #include <unistd.h> 39 #include <string.h> 40 #include <errno.h> 41 42 #include "test.h" 43 #include "safe_macros.h" 44 45 static int page_size, fds[2], epfd, inv_epfd, bad_epfd = -1; 46 47 static struct epoll_event epevs[1] = { 48 {.events = EPOLLOUT} 49 }; 50 51 static struct epoll_event *ev_rdwr = epevs; 52 static struct epoll_event *ev_rdonly; 53 54 static struct test_case_t { 55 int *epfd; 56 struct epoll_event **ev; 57 int maxevents; 58 int exp_errno; 59 } tc[] = { 60 /* test1 */ 61 {&bad_epfd, &ev_rdwr, 1, EBADF}, 62 /* test2 */ 63 {&inv_epfd, &ev_rdwr, 1, EINVAL}, 64 /* test3 */ 65 {&epfd, &ev_rdwr, -1, EINVAL}, 66 /* test4 */ 67 {&epfd, &ev_rdwr, 0, EINVAL}, 68 /* test5 */ 69 {&epfd, &ev_rdonly, 1, EFAULT} 70 }; 71 72 char *TCID = "epoll_wait03"; 73 int TST_TOTAL = ARRAY_SIZE(tc); 74 75 static void setup(void); 76 static void verify_epoll_wait(struct test_case_t *tc); 77 static void cleanup(void); 78 79 int main(int ac, char **av) 80 { 81 int lc, i; 82 83 tst_parse_opts(ac, av, NULL, NULL); 84 85 setup(); 86 87 for (lc = 0; TEST_LOOPING(lc); lc++) { 88 tst_count = 0; 89 90 for (i = 0; i < TST_TOTAL; i++) 91 verify_epoll_wait(&tc[i]); 92 } 93 94 cleanup(); 95 tst_exit(); 96 } 97 98 static void setup(void) 99 { 100 tst_sig(NOFORK, DEF_HANDLER, cleanup); 101 102 TEST_PAUSE; 103 104 page_size = getpagesize(); 105 106 ev_rdonly = SAFE_MMAP(NULL, NULL, page_size, PROT_READ, 107 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); 108 109 SAFE_PIPE(NULL, fds); 110 111 epfd = epoll_create(1); 112 if (epfd == -1) { 113 tst_brkm(TBROK | TERRNO, cleanup, 114 "failed to create epoll instance"); 115 } 116 117 epevs[0].data.fd = fds[1]; 118 119 if (epoll_ctl(epfd, EPOLL_CTL_ADD, fds[1], &epevs[0])) { 120 tst_brkm(TBROK | TERRNO, cleanup, 121 "failed to register epoll target"); 122 } 123 } 124 125 static void verify_epoll_wait(struct test_case_t *tc) 126 { 127 TEST(epoll_wait(*(tc->epfd), *(tc->ev), tc->maxevents, -1)); 128 if (TEST_RETURN != -1) { 129 tst_resm(TFAIL, "epoll_wait() succeed unexpectedly"); 130 } else { 131 if (tc->exp_errno == TEST_ERRNO) { 132 tst_resm(TPASS | TTERRNO, 133 "epoll_wait() fails as expected"); 134 } else { 135 tst_resm(TFAIL | TTERRNO, 136 "epoll_wait() fails unexpectedly, " 137 "expected %d: %s", tc->exp_errno, 138 tst_strerrno(tc->exp_errno)); 139 } 140 } 141 } 142 143 static void cleanup(void) 144 { 145 if (epfd > 0 && close(epfd)) 146 tst_resm(TWARN | TERRNO, "failed to close epfd"); 147 148 if (close(fds[0])) 149 tst_resm(TWARN | TERRNO, "close(fds[0]) failed"); 150 151 if (close(fds[1])) 152 tst_resm(TWARN | TERRNO, "close(fds[1]) failed"); 153 } 154