about summary refs log tree commit diff
path: root/library/std/src/sys/unix/mod.rs
diff options
context:
space:
mode:
authorTomasz Miąsko <tomasz.miasko@gmail.com>2022-05-08 00:00:00 +0000
committerTomasz Miąsko <tomasz.miasko@gmail.com>2022-05-11 09:38:28 +0200
commite0a53ed63ab9132b031153d1e69591195e97a59b (patch)
tree258f3b659e190a416232be6156c4fa1a5e9d686b /library/std/src/sys/unix/mod.rs
parentb862b438dbffb959ef4e9643148ecd05b8da4d8a (diff)
downloadrust-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.rs37
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();
                         }
                     }