From 2a8bc8331bd8203d260621ae2317c3cd1f829676 Mon Sep 17 00:00:00 2001
From: jD91mZM2 <me@krake.one>
Date: Sat, 22 Sep 2018 11:12:31 +0200
Subject: [PATCH] Fix select return value

---
 src/platform/redox/mod.rs | 65 +++++++++++++++++++++++++++++----------
 1 file changed, 49 insertions(+), 16 deletions(-)

diff --git a/src/platform/redox/mod.rs b/src/platform/redox/mod.rs
index 8b136d7b2..365885f90 100644
--- a/src/platform/redox/mod.rs
+++ b/src/platform/redox/mod.rs
@@ -635,9 +635,26 @@ impl Pal for Sys {
                 return false;
             }
 
-            let mask = 1 << (fd & (8 * mem::size_of::<c_ulong>() - 1));
+            let mask = 1 << (fd & 8 * mem::size_of::<c_ulong>() - 1);
             unsafe { (*set).fds_bits[fd / (8 * mem::size_of::<c_ulong>())] & mask == mask }
         }
+        fn clearset(set: *mut fd_set) {
+            if set.is_null() {
+                return;
+            }
+
+            for i in unsafe { &mut (*set).fds_bits } {
+                *i = 0;
+            }
+        }
+        fn set(set: *mut fd_set, fd: usize) {
+            if set.is_null() {
+                return;
+            }
+
+            let mask = 1 << (fd & 8 * mem::size_of::<c_ulong>() - 1);
+            unsafe { (*set).fds_bits[fd / (8 * mem::size_of::<c_ulong>())] |= mask; }
+        }
 
         let event_path = unsafe { CStr::from_bytes_with_nul_unchecked(b"event:\0") };
         let event_file = match RawFile::open(event_path, fcntl::O_RDWR | fcntl::O_CLOEXEC, 0) {
@@ -645,8 +662,6 @@ impl Pal for Sys {
             Err(_) => return -1,
         };
 
-        let mut total = 0;
-
         for fd in 0..nfds as usize {
             macro_rules! register {
                 ($fd:expr, $flags:expr) => {
@@ -665,14 +680,9 @@ impl Pal for Sys {
             }
             if isset(readfds, fd) {
                 register!(fd, syscall::EVENT_READ);
-                total += 1;
             }
             if isset(writefds, fd) {
                 register!(fd, syscall::EVENT_WRITE);
-                total += 1;
-            }
-            if isset(exceptfds, fd) {
-                total += 1;
             }
         }
 
@@ -725,17 +735,40 @@ impl Pal for Sys {
             Some(timeout_file)
         };
 
-        let mut event = syscall::Event::default();
-        if Self::read(*event_file, &mut event) < 0 {
-            return -1;
-        }
+        let mut events = [syscall::Event::default(); 32];
+        let read = {
+            let mut events = unsafe { slice::from_raw_parts_mut(
+                &mut events as *mut _ as *mut u8,
+                mem::size_of::<syscall::Event>() * events.len()
+            ) };
+            let read = Self::read(*event_file, &mut events);
+            if read < 0 {
+                return -1;
+            }
+            read as usize / mem::size_of::<syscall::Event>()
+        };
 
-        if timeout_file.is_some() && event.data == TIMEOUT_TOKEN {
-            return 0;
+        let mut total = 0;
+
+        clearset(readfds);
+        clearset(writefds);
+        clearset(exceptfds);
+
+        for event in &events[..read] {
+            if event.data == TIMEOUT_TOKEN {
+                continue;
+            }
+
+            if event.flags & syscall::EVENT_READ == syscall::EVENT_READ {
+                set(readfds, event.id);
+                total += 1;
+            }
+            if event.flags & syscall::EVENT_WRITE == syscall::EVENT_WRITE {
+                set(writefds, event.id);
+                total += 1;
+            }
         }
 
-        // I really don't get why, but select wants me to return the total number
-        // of file descriptors that was inputted. I'm confused.
         total
     }
 
-- 
GitLab