Home | History | Annotate | Download | only in epoll_wait
      1 /*
      2  * Copyright (c) 2016 Fujitsu Ltd.
      3  * Author: Guangwen Feng <fenggw-fnst (at) 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