Fix select return value

This commit is contained in:
jD91mZM2
2018-09-22 11:12:31 +02:00
parent b43299642b
commit 2a8bc8331b
+50 -17
View File
@@ -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>()
};
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;
}
}
if timeout_file.is_some() && event.data == TIMEOUT_TOKEN {
return 0;
}
// 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
}