File 0016-rb_fd_select-raise-exception-on-bad-fd-when-using-po.patch of Package ruby2.5
From 2dad46591978bd91198287666f4f1894a2bfe37a Mon Sep 17 00:00:00 2001
From: Michal Suchanek <msuchanek@suse.de>
Date: Mon, 24 Feb 2020 22:43:58 +0100
Subject: [PATCH 16/19] rb_fd_select: raise exception on bad fd when using
poll()
This aligns interface with select(), losing information saying which fd
is bad.
Signed-off-by: Michal Suchanek <msuchanek@suse.de>
---
thread.c | 34 ++++++++++++++++++++++++++++++----
1 file changed, 30 insertions(+), 4 deletions(-)
diff --git a/thread.c b/thread.c
index 95aacd2f5f13..76d60def5cf4 100644
--- a/thread.c
+++ b/thread.c
@@ -3710,11 +3710,24 @@ pollfdset_extract(struct rb_pollfdset *pollfdset, rb_fdset_t *fds, int flags)
rb_fd_set(pollfdset->fds[i].fd, fds);
}
+static bool
+pollfdset_badfd(struct rb_pollfdset *pollfdset)
+{
+ int i;
+
+ for (i = 0; i < pollfdset->n_fds; i++)
+ if (pollfdset->fds[i].revents & POLLNVAL)
+ return true;
+
+ return false;
+}
+
int
rb_fd_select(int n, rb_fdset_t *readfds, rb_fdset_t *writefds, rb_fdset_t *exceptfds, rb_fdset_t *errorfds, struct timeval *timeout)
{
struct rb_pollfdset pollfdset;
int timeout_ms = timeout ? timeout->tv_sec * 1000 + timeout->tv_usec / 1000 : -1;
+ bool badfd;
int ret;
pollfdset_init(&pollfdset);
@@ -3723,11 +3736,24 @@ rb_fd_select(int n, rb_fdset_t *readfds, rb_fdset_t *writefds, rb_fdset_t *excep
if (exceptfds) pollfdset_add(&pollfdset, exceptfds, POLLEX_SET);
if (errorfds) pollfdset_add(&pollfdset, errorfds, POLLERR_SET);
ret = poll(pollfdset.fds, pollfdset.n_fds, timeout_ms);
- if (readfds) pollfdset_extract(&pollfdset, readfds, POLLIN_SET);
- if (writefds) pollfdset_extract(&pollfdset, writefds, POLLOUT_SET);
- if (exceptfds) pollfdset_extract(&pollfdset, exceptfds, POLLEX_SET);
- if (errorfds) pollfdset_extract(&pollfdset, errorfds, POLLERR_SET);
+ badfd = pollfdset_badfd(&pollfdset);
+ if (badfd) {
+ if (readfds) rb_fd_zero(readfds);
+ if (writefds) rb_fd_zero(writefds);
+ if (exceptfds) rb_fd_zero(exceptfds);
+ if (errorfds) rb_fd_zero(errorfds);
+ } else {
+ if (readfds) pollfdset_extract(&pollfdset, readfds, POLLIN_SET);
+ if (writefds) pollfdset_extract(&pollfdset, writefds, POLLOUT_SET);
+ if (exceptfds) pollfdset_extract(&pollfdset, exceptfds, POLLEX_SET);
+ if (errorfds) pollfdset_extract(&pollfdset, errorfds, POLLERR_SET);
+ }
pollfdset_term(&pollfdset);
+
+ if (badfd) {
+ errno = EBADF;
+ return -EBADF;
+ }
return ret;
}
#else /* USE_POLL */
--
2.26.2