Print this page
OS-5518 devpoll write feigns success in the face of EINTR
OS-5520 epoll_ctl not allowed to emit EINTR
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Reviewed by: Bryan Cantrill <bryan@joyent.com>
OS-5459 epoll_ctl should throw EINVAL for loops
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>

*** 8,18 **** * source. A copy of the CDDL is also available via the Internet at * http://www.illumos.org/license/CDDL. */ /* ! * Copyright (c) 2014, Joyent, Inc. All rights reserved. */ #include <sys/types.h> #include <sys/epoll.h> #include <sys/devpoll.h> --- 8,18 ---- * source. A copy of the CDDL is also available via the Internet at * http://www.illumos.org/license/CDDL. */ /* ! * Copyright 2016 Joyent, Inc. */ #include <sys/types.h> #include <sys/epoll.h> #include <sys/devpoll.h>
*** 112,122 **** int 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; epoll[i].dpep_pollfd.fd = fd; switch (op) { case EPOLL_CTL_DEL: --- 112,122 ---- int 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, res; epoll[i].dpep_pollfd.fd = fd; switch (op) { case EPOLL_CTL_DEL:
*** 163,174 **** errno = EOPNOTSUPP; return (-1); } epoll[i].dpep_pollfd.events = ev; ! return (write(epfd, epoll, sizeof (epoll[0]) * (i + 1)) == -1 ? -1 : 0); } int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout) --- 163,195 ---- errno = EOPNOTSUPP; return (-1); } epoll[i].dpep_pollfd.events = ev; + 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 epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout)