about summary refs log tree commit diff
path: root/library/std/src/sys
diff options
context:
space:
mode:
authorJacob Pratt <jacob@jhpratt.dev>2025-08-21 17:57:48 -0400
committerGitHub <noreply@github.com>2025-08-21 17:57:48 -0400
commit0a0553e2e4fa19cb5d87286e0960bb984bf503aa (patch)
treee2bc19d17474d1c58649b76a1802f3ec4fe3a5b7 /library/std/src/sys
parent6ba0ce40941eee1ca02e9ba49c791ada5158747a (diff)
parentac761f28d15764887a0a1df4fa9067dcc7e0e94f (diff)
downloadrust-0a0553e2e4fa19cb5d87286e0960bb984bf503aa.tar.gz
rust-0a0553e2e4fa19cb5d87286e0960bb984bf503aa.zip
Rollup merge of #137494 - nabijaczleweli:dup, r=Mark-Simulacrum
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
```
Diffstat (limited to 'library/std/src/sys')
-rw-r--r--library/std/src/sys/pal/unix/mod.rs50
1 files changed, 26 insertions, 24 deletions
diff --git a/library/std/src/sys/pal/unix/mod.rs b/library/std/src/sys/pal/unix/mod.rs
index fede3673eb6..aef7ab55088 100644
--- a/library/std/src/sys/pal/unix/mod.rs
+++ b/library/std/src/sys/pal/unix/mod.rs
@@ -59,6 +59,30 @@ pub unsafe fn init(argc: isize, argv: *const *const u8, sigpipe: u8) {
     }
 
     unsafe fn sanitize_standard_fds() {
+        #[allow(dead_code, unused_variables, unused_mut)]
+        let mut opened_devnull = -1;
+        #[allow(dead_code, unused_variables, unused_mut)]
+        let mut open_devnull = || {
+            #[cfg(not(all(target_os = "linux", target_env = "gnu")))]
+            use libc::open;
+            #[cfg(all(target_os = "linux", target_env = "gnu"))]
+            use libc::open64 as open;
+
+            if opened_devnull != -1 {
+                if libc::dup(opened_devnull) != -1 {
+                    return;
+                }
+            }
+            opened_devnull = open(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,
@@ -74,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 },
@@ -106,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;
         }
@@ -129,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();
                 }
             }
         }