From 57a0264b71e479ed0dc19299607d662043907cb6 Mon Sep 17 00:00:00 2001 From: Patrick Mooney Date: Wed, 23 Mar 2016 19:35:31 +0000 Subject: 7422 dpioctl should pay attention to FKIOCTL 7423 epoll_ctl should throw EINVAL for loops 7424 epoll should not leave dangling polldat_t entries 7425 devpoll write feigns success in the face of EINTR 7426 epoll_ctl not allowed to emit EINTR Reviewed by: Jerry Jelinek Reviewed by: Bryan Cantrill Approved by: Dan McDonald --- usr/src/lib/libc/port/sys/epoll.c | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) (limited to 'usr/src/lib/libc') diff --git a/usr/src/lib/libc/port/sys/epoll.c b/usr/src/lib/libc/port/sys/epoll.c index 93379b583e..543856b2ec 100644 --- a/usr/src/lib/libc/port/sys/epoll.c +++ b/usr/src/lib/libc/port/sys/epoll.c @@ -10,7 +10,7 @@ */ /* - * Copyright (c) 2014, Joyent, Inc. All rights reserved. + * Copyright 2016 Joyent, Inc. */ #include @@ -114,7 +114,7 @@ epoll_ctl(int epfd, int op, int fd, struct epoll_event *event) { dvpoll_epollfd_t epoll[2]; uint32_t events, ev = 0; - int i = 0; + int i = 0, res; epoll[i].dpep_pollfd.fd = fd; @@ -165,8 +165,29 @@ epoll_ctl(int epfd, int op, int fd, struct epoll_event *event) } epoll[i].dpep_pollfd.events = ev; - - return (write(epfd, epoll, sizeof (epoll[0]) * (i + 1)) == -1 ? -1 : 0); +retry: + res = write(epfd, epoll, sizeof (epoll[0]) * (i + 1)); + + if (res == -1) { + if (errno == EINTR) { + /* + * Linux does not document EINTR as an allowed error + * for epoll_ctl. The write must be retried if it is + * not done automatically via SA_RESTART. + */ + goto retry; + } + if (errno == ELOOP) { + /* + * Convert the specific /dev/poll error about an fd + * loop into what is expected from the Linux epoll + * interface. + */ + errno = EINVAL; + } + return (-1); + } + return (0); } int -- cgit v1.2.3