Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
anastygnome opened this issue Feb 16, 2023 · 4 comments
Open

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

anastygnome opened this issue Feb 16, 2023 · 4 comments
Labels
C-enhancement Category: An issue proposing an enhancement or a PR with one. T-libs Relevant to the library team, which will review and decide on the PR/issue.

Comments

@anastygnome
Copy link

anastygnome commented Feb 16, 2023

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 ?

@anastygnome
Copy link
Author

anastygnome commented Feb 16, 2023

uutils/coreutils#2873

For example, some coreutils behaviour need to take into account this fact too.

@the8472
Copy link
Member

the8472 commented Feb 18, 2023

See also #88825. posix requires that descriptors 0-2 are open at program startup. So any program that wants to detect a closed descriptor is non-compliant.

@clubby789
Copy link
Contributor

@rustbot label +T-libs +C-enhancement

@rustbot rustbot added C-enhancement Category: An issue proposing an enhancement or a PR with one. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Mar 27, 2023
@anastygnome
Copy link
Author

See also #88825. posix requires that descriptors 0-2 are open at program startup. So any program that wants to detect a closed descriptor is non-compliant.

Sometimes, one needs to be non-compliant. Not all environments are, and I don't believe we should prevent people from doing it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-enhancement Category: An issue proposing an enhancement or a PR with one. T-libs Relevant to the library team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

4 participants