Skip to content
Snippets Groups Projects
Verified Commit 54fb8b9b authored by Jeremy Soller's avatar Jeremy Soller
Browse files

Fix select on regular files

parent ba711deb
No related branches found
No related tags found
No related merge requests found
......@@ -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 };
......
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
......@@ -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;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment