summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordchagin <dchagin@FreeBSD.org>2017-03-30 20:14:43 +0000
committerdchagin <dchagin@FreeBSD.org>2017-03-30 20:14:43 +0000
commit0c8318dc914dfce6474c5c02ac37d5e0601cbc39 (patch)
tree98c3d5442077d84895ae4d9f295e67614dee030c
parentdc4ba9a04b28852f351313825fd6a8194c97de8a (diff)
downloadFreeBSD-src-0c8318dc914dfce6474c5c02ac37d5e0601cbc39.zip
FreeBSD-src-0c8318dc914dfce6474c5c02ac37d5e0601cbc39.tar.gz
MFC r314404:
Linux epoll return EEXIST on case when op is EPOLL_CTL_ADD, and the supplied file descriptor fd is already registered with this epoll instance.
-rw-r--r--sys/compat/linux/linux_event.c28
1 files changed, 21 insertions, 7 deletions
diff --git a/sys/compat/linux/linux_event.c b/sys/compat/linux/linux_event.c
index 4c29186..84639c9 100644
--- a/sys/compat/linux/linux_event.c
+++ b/sys/compat/linux/linux_event.c
@@ -481,15 +481,34 @@ linux_epoll_ctl(struct thread *td, struct linux_epoll_ctl_args *args)
ciargs.changelist = kev;
+ if (args->op != LINUX_EPOLL_CTL_DEL) {
+ kev_flags = EV_ADD | EV_ENABLE;
+ error = epoll_to_kevent(td, epfp, args->fd, &le,
+ &kev_flags, kev, &nchanges);
+ if (error != 0)
+ goto leave0;
+ }
+
switch (args->op) {
case LINUX_EPOLL_CTL_MOD:
error = epoll_delete_all_events(td, epfp, args->fd);
if (error != 0)
goto leave0;
- /* FALLTHROUGH */
+ break;
case LINUX_EPOLL_CTL_ADD:
- kev_flags = EV_ADD | EV_ENABLE;
+ /*
+ * kqueue_register() return ENOENT if event does not exists
+ * and the EV_ADD flag is not set.
+ */
+ kev[0].flags &= ~EV_ADD;
+ error = kqfd_register(args->epfd, &kev[0], td, 1);
+ if (error != ENOENT) {
+ error = EEXIST;
+ goto leave0;
+ }
+ error = 0;
+ kev[0].flags |= EV_ADD;
break;
case LINUX_EPOLL_CTL_DEL:
@@ -502,11 +521,6 @@ linux_epoll_ctl(struct thread *td, struct linux_epoll_ctl_args *args)
goto leave0;
}
- error = epoll_to_kevent(td, epfp, args->fd, &le, &kev_flags,
- kev, &nchanges);
- if (error != 0)
- goto leave0;
-
epoll_fd_install(td, args->fd, le.data);
error = kern_kevent_fp(td, epfp, nchanges, 0, &k_ops, NULL);
OpenPOWER on IntegriCloud