Skip to content

Need to check if the std{in,err,out} file descriptors status #108139

Open
@anastygnome

Description

@anastygnome

Hello,

I was faced with a difficulty earlier today as I needed to port an application whose behaviour depends upon the status of those three file descriptors.

I have tracked the issue down to the following function :

unsafe fn sanitize_standard_fds() {
// fast path with a single syscall for systems with poll()
#[cfg(not(any(
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 = "watchos",
target_os = "redox",
target_os = "l4re",
target_os = "horizon",
)))]
'poll: {
use crate::sys::os::errno;
#[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;
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 {
match errno() {
libc::EINTR => continue,
libc::EINVAL | libc::EAGAIN | libc::ENOMEM => {
// RLIMIT_NOFILE or temporary allocation failures
// may be preventing use of poll(), fall back to fcntl
break 'poll;
}
_ => libc::abort(),
}
}
for pfd in pfds {
if pfd.revents & libc::POLLNVAL == 0 {
continue;
}
if open64("/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();
}
}
return;
}

I am of the opinion that, even if the std library needs to reopen those descriptors, we should be able to get an indication that those are not the original ones. Maybe through some kind of booleans or a dedicated structure?
Related: #47271
This has also affected the uutils project.
Any hope this will get fixed ?

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-enhancementCategory: An issue proposing an enhancement or a PR with one.T-libsRelevant to the library team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions