Skip to content

Commit 8df6f26

Browse files
committed
Use fcntl(fd, F_GETFD) to detect if standard streams are open
In the previous implementation, if the standard streams were open, but the RLIMIT_NOFILE value was below three, the poll would fail with EINVAL: > ERRORS: EINVAL The nfds value exceeds the RLIMIT_NOFILE value. Switch to the existing fcntl based implementation to avoid the issue.
1 parent b653940 commit 8df6f26

File tree

1 file changed

+6
-31
lines changed

1 file changed

+6
-31
lines changed

std/src/sys/unix/mod.rs

Lines changed: 6 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -67,48 +67,23 @@ pub unsafe fn init(argc: isize, argv: *const *const u8) {
6767
args::init(argc, argv);
6868

6969
unsafe fn sanitize_standard_fds() {
70-
#[cfg(not(miri))]
71-
// The standard fds are always available in Miri.
7270
cfg_if::cfg_if! {
7371
if #[cfg(not(any(
72+
// The standard fds are always available in Miri.
73+
miri,
7474
target_os = "emscripten",
7575
target_os = "fuchsia",
7676
target_os = "vxworks",
77-
// The poll on Darwin doesn't set POLLNVAL for closed fds.
78-
target_os = "macos",
79-
target_os = "ios",
80-
target_os = "redox",
8177
target_os = "l4re",
8278
)))] {
83-
use crate::sys::os::errno;
84-
let pfds: &mut [_] = &mut [
85-
libc::pollfd { fd: 0, events: 0, revents: 0 },
86-
libc::pollfd { fd: 1, events: 0, revents: 0 },
87-
libc::pollfd { fd: 2, events: 0, revents: 0 },
88-
];
89-
while libc::poll(pfds.as_mut_ptr(), 3, 0) == -1 {
90-
if errno() == libc::EINTR {
91-
continue;
92-
}
93-
libc::abort();
94-
}
95-
for pfd in pfds {
96-
if pfd.revents & libc::POLLNVAL == 0 {
97-
continue;
98-
}
99-
if libc::open("/dev/null\0".as_ptr().cast(), libc::O_RDWR, 0) == -1 {
100-
// If the stream is closed but we failed to reopen it, abort the
101-
// process. Otherwise we wouldn't preserve the safety of
102-
// operations on the corresponding Rust object Stdin, Stdout, or
103-
// Stderr.
104-
libc::abort();
105-
}
106-
}
107-
} else if #[cfg(any(target_os = "macos", target_os = "ios", target_os = "redox"))] {
10879
use crate::sys::os::errno;
10980
for fd in 0..3 {
11081
if libc::fcntl(fd, libc::F_GETFD) == -1 && errno() == libc::EBADF {
11182
if libc::open("/dev/null\0".as_ptr().cast(), libc::O_RDWR, 0) == -1 {
83+
// If the stream is closed but we failed to reopen it, abort the
84+
// process. Otherwise we wouldn't preserve the safety of
85+
// operations on the corresponding Rust object Stdin, Stdout, or
86+
// Stderr.
11287
libc::abort();
11388
}
11489
}

0 commit comments

Comments
 (0)