mirror of
https://github.com/rust-lang/rust.git
synced 2026-04-30 06:43:20 +03:00
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
```
This commit is contained in:
@@ -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 @@ unsafe fn sanitize_standard_fds() {
|
||||
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 @@ unsafe fn sanitize_standard_fds() {
|
||||
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 @@ unsafe fn sanitize_standard_fds() {
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user