about summary refs log tree commit diff
diff options
context:
space:
mode:
authorнаб <nabijaczleweli@nabijaczleweli.xyz>2025-02-23 19:40:57 +0100
committerнаб <nabijaczleweli@nabijaczleweli.xyz>2025-02-23 20:22:30 +0100
commit4983fdaada0c78d48e57f177453e5b954d5caad3 (patch)
treebc099fe67878400c3f1a1052508e3279ca5ee105
parentb522e7c5ea8334fbccb9dd7f9b33759304743fd0 (diff)
downloadrust-4983fdaada0c78d48e57f177453e5b954d5caad3.tar.gz
rust-4983fdaada0c78d48e57f177453e5b954d5caad3.zip
libstd: init(): dup() subsequent /dev/nulls instead of opening them again
This will be faster, and also it deduplicates the code so win/win

The dup() is actually infallible here. But whatever.

Before:
    poll([{fd=0, events=0}, {fd=1, events=0}, {fd=2, events=0}], 3, 0) = 1 ([{fd=2, revents=POLLNVAL}])
    openat(AT_FDCWD, "/dev/null", O_RDWR)   = 2
    rt_sigaction(SIGPIPE, {sa_handler=SIG_IGN, sa_mask=[PIPE], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0x7f5749313050}, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0

    poll([{fd=0, events=0}, {fd=1, events=0}, {fd=2, events=0}], 3, 0) = 2 ([{fd=0, revents=POLLNVAL}, {fd=2, revents=POLLNVAL}])
    openat(AT_FDCWD, "/dev/null", O_RDWR)   = 0
    openat(AT_FDCWD, "/dev/null", O_RDWR)   = 2
    rt_sigaction(SIGPIPE, {sa_handler=SIG_IGN, sa_mask=[PIPE], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0x7efe12006050}, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0

    poll([{fd=0, events=0}, {fd=1, events=0}, {fd=2, events=0}], 3, 0) = 3 ([{fd=0, revents=POLLNVAL}, {fd=1, revents=POLLNVAL}, {fd=2, revents=POLLNVAL}])
    openat(AT_FDCWD, "/dev/null", O_RDWR)   = 0
    openat(AT_FDCWD, "/dev/null", O_RDWR)   = 1
    openat(AT_FDCWD, "/dev/null", O_RDWR)   = 2
    rt_sigaction(SIGPIPE, {sa_handler=SIG_IGN, sa_mask=[PIPE], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0x7fc2dc7ca050}, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0

After:
    poll([{fd=0, events=0}, {fd=1, events=0}, {fd=2, events=0}], 3, 0) = 1 ([{fd=1, revents=POLLNVAL}])
    openat(AT_FDCWD, "/dev/null", O_RDWR)   = 1
    rt_sigaction(SIGPIPE, {sa_handler=SIG_IGN, sa_mask=[PIPE], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0x7f488a3fb050}, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0

    poll([{fd=0, events=0}, {fd=1, events=0}, {fd=2, events=0}], 3, 0) = 2 ([{fd=1, revents=POLLNVAL}, {fd=2, revents=POLLNVAL}])
    openat(AT_FDCWD, "/dev/null", O_RDWR)   = 1
    dup(1)                                  = 2
    rt_sigaction(SIGPIPE, {sa_handler=SIG_IGN, sa_mask=[PIPE], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0x7f1a8943c050}, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0

    poll([{fd=0, events=0}, {fd=1, events=0}, {fd=2, events=0}], 3, 0) = 3 ([{fd=0, revents=POLLNVAL}, {fd=1, revents=POLLNVAL}, {fd=2, revents=POLLNVAL}])
    openat(AT_FDCWD, "/dev/null", O_RDWR)   = 0
    dup(0)                                  = 1
    dup(0)                                  = 2
    rt_sigaction(SIGPIPE, {sa_handler=SIG_IGN, sa_mask=[PIPE], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0x7f4e3a4c7050}, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
-rw-r--r--library/std/src/sys/pal/unix/mod.rs48
1 files changed, 24 insertions, 24 deletions
diff --git a/library/std/src/sys/pal/unix/mod.rs b/library/std/src/sys/pal/unix/mod.rs
index c0b56d8d2b2..ec61fcad7e8 100644
--- a/library/std/src/sys/pal/unix/mod.rs
+++ b/library/std/src/sys/pal/unix/mod.rs
@@ -61,6 +61,28 @@ pub unsafe fn init(argc: isize, argv: *const *const u8, sigpipe: u8) {
     }
 
     unsafe fn sanitize_standard_fds() {
+        let mut opened_devnull = -1;
+        let mut open_devnull = || {
+            #[cfg(not(all(target_os = "linux", target_env = "gnu")))]
+            use libc::open as open64;
+            #[cfg(all(target_os = "linux", target_env = "gnu"))]
+            use libc::open64;
+
+            if opened_devnull != -1 {
+                if libc::dup(opened_devnull) != -1 {
+                    return;
+                }
+            }
+            opened_devnull = open64(c"/dev/null".as_ptr(), libc::O_RDWR, 0);
+            if opened_devnull == -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();
+            }
+        };
+
         // fast path with a single syscall for systems with poll()
         #[cfg(not(any(
             miri,
@@ -76,11 +98,6 @@ pub unsafe fn init(argc: isize, argv: *const *const u8, sigpipe: u8) {
             target_vendor = "apple",
         )))]
         'poll: {
-            #[cfg(not(all(target_os = "linux", target_env = "gnu")))]
-            use libc::open as open64;
-            #[cfg(all(target_os = "linux", target_env = "gnu"))]
-            use libc::open64;
-
             use crate::sys::os::errno;
             let pfds: &mut [_] = &mut [
                 libc::pollfd { fd: 0, events: 0, revents: 0 },
@@ -108,13 +125,7 @@ pub unsafe fn init(argc: isize, argv: *const *const u8, sigpipe: u8) {
                 if pfd.revents & libc::POLLNVAL == 0 {
                     continue;
                 }
-                if open64(c"/dev/null".as_ptr(), 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();
-                }
+                open_devnull();
             }
             return;
         }
@@ -131,21 +142,10 @@ pub unsafe fn init(argc: isize, argv: *const *const u8, sigpipe: u8) {
             target_os = "vita",
         )))]
         {
-            #[cfg(not(all(target_os = "linux", target_env = "gnu")))]
-            use libc::open as open64;
-            #[cfg(all(target_os = "linux", target_env = "gnu"))]
-            use libc::open64;
-
             use crate::sys::os::errno;
             for fd in 0..3 {
                 if libc::fcntl(fd, libc::F_GETFD) == -1 && errno() == libc::EBADF {
-                    if open64(c"/dev/null".as_ptr(), 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();
-                    }
+                    open_devnull();
                 }
             }
         }