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)