diff options
| author | Tomasz Miąsko <tomasz.miasko@gmail.com> | 2022-05-08 00:00:00 +0000 | 
|---|---|---|
| committer | Tomasz Miąsko <tomasz.miasko@gmail.com> | 2022-05-11 09:38:28 +0200 | 
| commit | e0a53ed63ab9132b031153d1e69591195e97a59b (patch) | |
| tree | 258f3b659e190a416232be6156c4fa1a5e9d686b /library/std/src/sys/unix/mod.rs | |
| parent | b862b438dbffb959ef4e9643148ecd05b8da4d8a (diff) | |
| download | rust-e0a53ed63ab9132b031153d1e69591195e97a59b.tar.gz rust-e0a53ed63ab9132b031153d1e69591195e97a59b.zip | |
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.
Diffstat (limited to 'library/std/src/sys/unix/mod.rs')
| -rw-r--r-- | library/std/src/sys/unix/mod.rs | 37 | 
1 files changed, 6 insertions, 31 deletions
| diff --git a/library/std/src/sys/unix/mod.rs b/library/std/src/sys/unix/mod.rs index 8e909aab7f0..d823e51afa2 100644 --- a/library/std/src/sys/unix/mod.rs +++ b/library/std/src/sys/unix/mod.rs @@ -67,48 +67,23 @@ pub unsafe fn init(argc: isize, argv: *const *const u8) { args::init(argc, argv); unsafe fn sanitize_standard_fds() { - #[cfg(not(miri))] - // The standard fds are always available in Miri. cfg_if::cfg_if! { if #[cfg(not(any( + // The standard fds are always available in Miri. + miri, target_os = "emscripten", target_os = "fuchsia", target_os = "vxworks", - // The poll on Darwin doesn't set POLLNVAL for closed fds. - target_os = "macos", - target_os = "ios", - target_os = "redox", target_os = "l4re", )))] { use crate::sys::os::errno; - let pfds: &mut [_] = &mut [ - libc::pollfd { fd: 0, events: 0, revents: 0 }, - libc::pollfd { fd: 1, events: 0, revents: 0 }, - libc::pollfd { fd: 2, events: 0, revents: 0 }, - ]; - while libc::poll(pfds.as_mut_ptr(), 3, 0) == -1 { - if errno() == libc::EINTR { - continue; - } - libc::abort(); - } - for pfd in pfds { - if pfd.revents & libc::POLLNVAL == 0 { - continue; - } - if libc::open("/dev/null\0".as_ptr().cast(), libc::O_RDWR, 0) == -1 { - // If the stream is closed but we failed to reopen it, abort the - // process. Otherwise we wouldn't preserve the safety of - // operations on the corresponding Rust object Stdin, Stdout, or - // Stderr. - libc::abort(); - } - } - } else if #[cfg(any(target_os = "macos", target_os = "ios", target_os = "redox"))] { - use crate::sys::os::errno; for fd in 0..3 { if libc::fcntl(fd, libc::F_GETFD) == -1 && errno() == libc::EBADF { if libc::open("/dev/null\0".as_ptr().cast(), libc::O_RDWR, 0) == -1 { + // If the stream is closed but we failed to reopen it, abort the + // process. Otherwise we wouldn't preserve the safety of + // operations on the corresponding Rust object Stdin, Stdout, or + // Stderr. libc::abort(); } } | 
