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

openSUSE Build Service is sponsored by