Skip to content

Commit 33250c4

Browse files
committed
Auto merge of #4477 - alexcrichton:fix-out-of-bounds, r=matklad
Use poll instead of select to handle large fds It may be the case that Cargo's running around with a lot of file descriptors, and in this case we wouldn't be able to call `select` due to the file descriptors being too large and not fitting in the bit array. This switches to what the standard library is currently doing, using `poll`, which doesn't have this limitations.
2 parents b8b66ef + 2380c9e commit 33250c4

File tree

1 file changed

+8
-15
lines changed

1 file changed

+8
-15
lines changed

src/cargo/util/read2.rs

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ pub use self::imp::read2;
22

33
#[cfg(unix)]
44
mod imp {
5-
use std::cmp;
65
use std::io::prelude::*;
76
use std::io;
87
use std::mem;
@@ -23,20 +22,14 @@ mod imp {
2322
let mut out = Vec::new();
2423
let mut err = Vec::new();
2524

26-
let max = cmp::max(out_pipe.as_raw_fd(), err_pipe.as_raw_fd());
25+
let mut fds: [libc::pollfd; 2] = unsafe { mem::zeroed() };
26+
fds[0].fd = out_pipe.as_raw_fd();
27+
fds[0].events = libc::POLLIN;
28+
fds[1].fd = err_pipe.as_raw_fd();
29+
fds[1].events = libc::POLLIN;
2730
loop {
2831
// wait for either pipe to become readable using `select`
29-
let r = unsafe {
30-
let mut read: libc::fd_set = mem::zeroed();
31-
if !out_done {
32-
libc::FD_SET(out_pipe.as_raw_fd(), &mut read);
33-
}
34-
if !err_done {
35-
libc::FD_SET(err_pipe.as_raw_fd(), &mut read);
36-
}
37-
libc::select(max + 1, &mut read, 0 as *mut _, 0 as *mut _,
38-
0 as *mut _)
39-
};
32+
let r = unsafe { libc::poll(fds.as_mut_ptr(), 2, -1) };
4033
if r == -1 {
4134
let err = io::Error::last_os_error();
4235
if err.kind() == io::ErrorKind::Interrupted {
@@ -62,11 +55,11 @@ mod imp {
6255
}
6356
}
6457
};
65-
if !out_done && handle(out_pipe.read_to_end(&mut out))? {
58+
if !out_done && fds[0].revents != 0 && handle(out_pipe.read_to_end(&mut out))? {
6659
out_done = true;
6760
}
6861
data(true, &mut out, out_done);
69-
if !err_done && handle(err_pipe.read_to_end(&mut err))? {
62+
if !err_done && fds[1].revents != 0 && handle(err_pipe.read_to_end(&mut err))? {
7063
err_done = true;
7164
}
7265
data(false, &mut err, err_done);

0 commit comments

Comments
 (0)