Skip to content

Commit 4983fda

Browse files
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
1 parent b522e7c commit 4983fda

File tree

1 file changed

+24
-24
lines changed
  • library/std/src/sys/pal/unix

1 file changed

+24
-24
lines changed

library/std/src/sys/pal/unix/mod.rs

+24-24
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,28 @@ pub unsafe fn init(argc: isize, argv: *const *const u8, sigpipe: u8) {
6161
}
6262

6363
unsafe fn sanitize_standard_fds() {
64+
let mut opened_devnull = -1;
65+
let mut open_devnull = || {
66+
#[cfg(not(all(target_os = "linux", target_env = "gnu")))]
67+
use libc::open as open64;
68+
#[cfg(all(target_os = "linux", target_env = "gnu"))]
69+
use libc::open64;
70+
71+
if opened_devnull != -1 {
72+
if libc::dup(opened_devnull) != -1 {
73+
return;
74+
}
75+
}
76+
opened_devnull = open64(c"/dev/null".as_ptr(), libc::O_RDWR, 0);
77+
if opened_devnull == -1 {
78+
// If the stream is closed but we failed to reopen it, abort the
79+
// process. Otherwise we wouldn't preserve the safety of
80+
// operations on the corresponding Rust object Stdin, Stdout, or
81+
// Stderr.
82+
libc::abort();
83+
}
84+
};
85+
6486
// fast path with a single syscall for systems with poll()
6587
#[cfg(not(any(
6688
miri,
@@ -76,11 +98,6 @@ pub unsafe fn init(argc: isize, argv: *const *const u8, sigpipe: u8) {
7698
target_vendor = "apple",
7799
)))]
78100
'poll: {
79-
#[cfg(not(all(target_os = "linux", target_env = "gnu")))]
80-
use libc::open as open64;
81-
#[cfg(all(target_os = "linux", target_env = "gnu"))]
82-
use libc::open64;
83-
84101
use crate::sys::os::errno;
85102
let pfds: &mut [_] = &mut [
86103
libc::pollfd { fd: 0, events: 0, revents: 0 },
@@ -108,13 +125,7 @@ pub unsafe fn init(argc: isize, argv: *const *const u8, sigpipe: u8) {
108125
if pfd.revents & libc::POLLNVAL == 0 {
109126
continue;
110127
}
111-
if open64(c"/dev/null".as_ptr(), libc::O_RDWR, 0) == -1 {
112-
// If the stream is closed but we failed to reopen it, abort the
113-
// process. Otherwise we wouldn't preserve the safety of
114-
// operations on the corresponding Rust object Stdin, Stdout, or
115-
// Stderr.
116-
libc::abort();
117-
}
128+
open_devnull();
118129
}
119130
return;
120131
}
@@ -131,21 +142,10 @@ pub unsafe fn init(argc: isize, argv: *const *const u8, sigpipe: u8) {
131142
target_os = "vita",
132143
)))]
133144
{
134-
#[cfg(not(all(target_os = "linux", target_env = "gnu")))]
135-
use libc::open as open64;
136-
#[cfg(all(target_os = "linux", target_env = "gnu"))]
137-
use libc::open64;
138-
139145
use crate::sys::os::errno;
140146
for fd in 0..3 {
141147
if libc::fcntl(fd, libc::F_GETFD) == -1 && errno() == libc::EBADF {
142-
if open64(c"/dev/null".as_ptr(), libc::O_RDWR, 0) == -1 {
143-
// If the stream is closed but we failed to reopen it, abort the
144-
// process. Otherwise we wouldn't preserve the safety of
145-
// operations on the corresponding Rust object Stdin, Stdout, or
146-
// Stderr.
147-
libc::abort();
148-
}
148+
open_devnull();
149149
}
150150
}
151151
}

0 commit comments

Comments
 (0)