Fix select on regular files
This commit is contained in:
@@ -72,8 +72,10 @@ pub fn select_epoll(
|
||||
File::new(epfd)
|
||||
};
|
||||
|
||||
// Keep track of the number of file descriptors that do not support epoll
|
||||
let mut not_epoll = 0;
|
||||
for fd in 0..nfds {
|
||||
if let Some(ref fd_set) = readfds {
|
||||
if let Some(ref mut fd_set) = readfds {
|
||||
if fd_set.isset(fd) {
|
||||
let mut event = epoll_event {
|
||||
events: EPOLLIN,
|
||||
@@ -82,11 +84,17 @@ pub fn select_epoll(
|
||||
},
|
||||
};
|
||||
if epoll_ctl(*ep, EPOLL_CTL_ADD, fd, &mut event) < 0 {
|
||||
return -1;
|
||||
if unsafe { platform::errno == errno::EPERM } {
|
||||
not_epoll += 1;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
fd_set.clr(fd);
|
||||
}
|
||||
}
|
||||
}
|
||||
if let Some(ref fd_set) = writefds {
|
||||
if let Some(ref mut fd_set) = writefds {
|
||||
if fd_set.isset(fd) {
|
||||
let mut event = epoll_event {
|
||||
events: EPOLLOUT,
|
||||
@@ -95,11 +103,17 @@ pub fn select_epoll(
|
||||
},
|
||||
};
|
||||
if epoll_ctl(*ep, EPOLL_CTL_ADD, fd, &mut event) < 0 {
|
||||
return -1;
|
||||
if unsafe { platform::errno == errno::EPERM } {
|
||||
not_epoll += 1;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
fd_set.clr(fd);
|
||||
}
|
||||
}
|
||||
}
|
||||
if let Some(ref fd_set) = exceptfds {
|
||||
if let Some(ref mut fd_set) = exceptfds {
|
||||
if fd_set.isset(fd) {
|
||||
let mut event = epoll_event {
|
||||
events: EPOLLERR,
|
||||
@@ -108,17 +122,23 @@ pub fn select_epoll(
|
||||
},
|
||||
};
|
||||
if epoll_ctl(*ep, EPOLL_CTL_ADD, fd, &mut event) < 0 {
|
||||
return -1;
|
||||
if unsafe { platform::errno == errno::EPERM } {
|
||||
not_epoll += 1;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
fd_set.clr(fd);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mut events: [epoll_event; 32] = unsafe { mem::zeroed() };
|
||||
let res = epoll_wait(
|
||||
*ep,
|
||||
events.as_mut_ptr(),
|
||||
events.len() as c_int,
|
||||
let epoll_timeout = if not_epoll > 0 {
|
||||
// Do not wait if any non-epoll file descriptors were found
|
||||
0
|
||||
} else {
|
||||
match timeout {
|
||||
Some(timeout) => {
|
||||
//TODO: Check for overflow
|
||||
@@ -127,22 +147,18 @@ pub fn select_epoll(
|
||||
},
|
||||
None => -1
|
||||
}
|
||||
};
|
||||
let res = epoll_wait(
|
||||
*ep,
|
||||
events.as_mut_ptr(),
|
||||
events.len() as c_int,
|
||||
epoll_timeout
|
||||
);
|
||||
if res < 0 {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if let Some(ref mut fd_set) = readfds {
|
||||
fd_set.zero();
|
||||
}
|
||||
if let Some(ref mut fd_set) = writefds {
|
||||
fd_set.zero();
|
||||
}
|
||||
if let Some(ref mut fd_set) = exceptfds {
|
||||
fd_set.zero();
|
||||
}
|
||||
|
||||
let mut count = 0;
|
||||
let mut count = not_epoll;
|
||||
for i in 0..res as usize {
|
||||
let event = &events[i];
|
||||
let fd = unsafe { event.data.fd };
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
Testing select on file
|
||||
Is set before? 1
|
||||
Amount of things ready: 1
|
||||
Is set after? 1
|
||||
Testing select on pipe
|
||||
Is set before? 1
|
||||
Amount of things ready: 1
|
||||
Is set after? 1
|
||||
|
||||
+44
-3
@@ -5,7 +5,36 @@
|
||||
|
||||
#include "test_helpers.h"
|
||||
|
||||
int main(void) {
|
||||
int file_test(void) {
|
||||
int fd = open("select.c", 0, 0);
|
||||
if (fd < 0) {
|
||||
perror("open");
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("Testing select on file\n");
|
||||
|
||||
fd_set read;
|
||||
FD_ZERO(&read);
|
||||
FD_SET(fd, &read);
|
||||
|
||||
printf("Is set before? %d\n", FD_ISSET(fd, &read));
|
||||
|
||||
int nfds = select(fd + 1, &read, NULL, NULL, NULL);
|
||||
if (nfds < 0) {
|
||||
perror("select");
|
||||
return 1;
|
||||
}
|
||||
printf("Amount of things ready: %d\n", nfds);
|
||||
|
||||
printf("Is set after? %d\n", FD_ISSET(fd, &read));
|
||||
|
||||
close(fd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pipe_test(void) {
|
||||
int pipefd[2];
|
||||
if (pipe2(pipefd, O_NONBLOCK) < 0) {
|
||||
perror("pipe");
|
||||
@@ -18,14 +47,14 @@ int main(void) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("Testing select on pipe\n");
|
||||
|
||||
fd_set read;
|
||||
FD_ZERO(&read);
|
||||
FD_SET(pipefd[0], &read);
|
||||
|
||||
printf("Is set before? %d\n", FD_ISSET(pipefd[0], &read));
|
||||
|
||||
// This should actually test TCP streams and stuff, but for now I'm simply
|
||||
// testing whether it ever returns or not.
|
||||
int nfds = select(pipefd[0] + 1, &read, NULL, NULL, NULL);
|
||||
if (nfds < 0) {
|
||||
perror("select");
|
||||
@@ -40,3 +69,15 @@ int main(void) {
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
if (file_test()) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (pipe_test()) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user