19f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang/*
29f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang * Copyright (c) 2016 Fujitsu Ltd.
39f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang * Author: Xiao Yang <yangx.jy@cn.fujitsu.com>
49f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang *
59f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang * This program is free software; you can redistribute it and/or modify it
69f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang * under the terms of version 2 of the GNU General Public License as
79f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang * published by the Free Software Foundation.
89f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang *
99f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang * This program is distributed in the hope that it would be useful, but
109f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang * WITHOUT ANY WARRANTY; without even the implied warranty of
119f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
129f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang *
139f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang * You should have received a copy of the GNU General Public License
149f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang * alone with this program.
159f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang */
169f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang
179f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang/*
189f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang * Test Name: epoll_ctl02.c
199f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang *
209f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang * Description:
219f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang * 1) epoll_ctl(2) fails if epfd is a invalid file descriptor.
229f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang * 2) epoll_ctl(2) fails if fd is a invalid file descriptor.
239f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang * 3) epoll_ctl(2) fails if op is not supported by this interface.
249f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang * 4) epoll_ctl(2) fails if fd is the same as epfd.
259f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang * 5) epoll_ctl(2) fails with EPOLL_CTL_DEL if fd is not registered
269f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang *    with this epoll instance.
279f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang * 6) epoll_ctl(2) fails with EPOLL_CTL_MOD if fd is not registered
289f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang *    with this epoll instance.
299f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang * 7) epoll_ctl(2) fails with EPOLL_CTL_ADD if fd is already registered
309f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang *    with this epoll instance.
319f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang *
329f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang * Expected Result:
339f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang * 1) epoll_ctl(2) should return -1 and set errno to EBADF.
349f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang * 2) epoll_ctl(2) should return -1 and set errno to EBADF.
359f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang * 3) epoll_ctl(2) should return -1 and set errno to EINVAL.
369f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang * 4) epoll_ctl(2) should return -1 and set errno to EINVAL.
379f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang * 5) epoll_ctl(2) should return -1 and set errno to ENOENT.
389f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang * 6) epoll_ctl(2) should return -1 and set errno to ENOENT.
399f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang * 7) epoll_ctl(2) should return -1 and set errno to EEXIST.
409f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang *
419f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang */
429f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang#include <sys/epoll.h>
439f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang#include <poll.h>
449f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang#include <errno.h>
459f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang#include "tst_test.h"
469f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang
479f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yangstatic int epfd;
489f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yangstatic int fd[2];
499f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yangstatic int inv = -1;
509f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang
519f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yangstatic struct epoll_event events[2] = {
529f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang	{.events = EPOLLIN},
539f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang	{.events = EPOLLOUT},
549f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang};
559f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang
569f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yangstatic struct testcase {
579f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang	int *epfds;
589f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang	int opt;
599f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang	int *fds;
609f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang	struct epoll_event *ts_event;
619f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang	int exp_err;
629f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang} tcases[] = {
639f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang	{&inv, EPOLL_CTL_ADD, &fd[1], &events[1], EBADF},
649f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang	{&epfd, EPOLL_CTL_ADD, &inv, &events[1], EBADF},
659f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang	{&epfd, -1, &fd[1], &events[1], EINVAL},
669f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang	{&epfd, EPOLL_CTL_ADD, &epfd, &events[1], EINVAL},
679f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang	{&epfd, EPOLL_CTL_DEL, &fd[1], &events[1], ENOENT},
689f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang	{&epfd, EPOLL_CTL_MOD, &fd[1], &events[1], ENOENT},
699f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang	{&epfd, EPOLL_CTL_ADD, &fd[0], &events[0], EEXIST}
709f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang};
719f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang
729f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yangstatic void setup(void)
739f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang{
749f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang	epfd = epoll_create(2);
759f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang	if (epfd == -1)
769f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang		tst_brk(TBROK | TERRNO, "fail to create epoll instance");
779f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang
789f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang	SAFE_PIPE(fd);
799f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang
809f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang	events[0].data.fd = fd[0];
819f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang	events[1].data.fd = fd[1];
829f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang
839f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang	TEST(epoll_ctl(epfd, EPOLL_CTL_ADD, fd[0], &events[0]));
849f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang	if (TEST_RETURN == -1)
859f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang		tst_brk(TFAIL | TTERRNO, "epoll_ctl() fails to init");
869f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang}
879f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang
889f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yangstatic void cleanup(void)
899f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang{
90e1c49edf1e9a7de95250c6aa6b122723531934ecCyril Hrubis	if (epfd)
91e1c49edf1e9a7de95250c6aa6b122723531934ecCyril Hrubis		SAFE_CLOSE(epfd);
92a98e153433f53a8c8067e1a59762bf177e3b1a9dXiao Yang
93e1c49edf1e9a7de95250c6aa6b122723531934ecCyril Hrubis	if (fd[0])
94e1c49edf1e9a7de95250c6aa6b122723531934ecCyril Hrubis		SAFE_CLOSE(fd[0]);
95a98e153433f53a8c8067e1a59762bf177e3b1a9dXiao Yang
96e1c49edf1e9a7de95250c6aa6b122723531934ecCyril Hrubis	if (fd[1])
97e1c49edf1e9a7de95250c6aa6b122723531934ecCyril Hrubis		SAFE_CLOSE(fd[1]);
989f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang}
999f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang
1009f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yangstatic void verify_epoll_ctl(unsigned int n)
1019f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang{
1029f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang	struct testcase *tc = &tcases[n];
1039f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang
1049f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang	TEST(epoll_ctl(*tc->epfds, tc->opt, *tc->fds,  tc->ts_event));
1059f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang	if (TEST_RETURN != -1) {
1069f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang		tst_res(TFAIL, "epoll_ctl() succeeds unexpectedly");
1079f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang		return;
1089f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang	}
1099f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang
1109f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang	if (tc->exp_err == TEST_ERRNO) {
1119f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang		tst_res(TPASS | TTERRNO, "epoll_ctl() fails as expected");
1129f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang	} else {
1139f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang		tst_res(TFAIL | TTERRNO,
1149f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang			"epoll_ctl() fails unexpectedly, expected %i: %s",
1159f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang			tc->exp_err, tst_strerrno(tc->exp_err));
1169f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang	}
1179f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang}
1189f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang
1199f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yangstatic struct tst_test test = {
1209f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang	.tid = "epoll_ctl02",
1219f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang	.tcnt = ARRAY_SIZE(tcases),
1229f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang	.setup = setup,
1239f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang	.cleanup = cleanup,
1249f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang	.test = verify_epoll_ctl,
1259f05efa44274dfb5305be283c1e71b9281d6eeb9Xiao Yang};
126