tail: add check to detect a closed file descriptor

This is WIP or even WONT-FIX because there's a workaround in Rust's
stdlib which prevents us from detecting a closed FD.

see also the discussion at:
https://github.com/uutils/coreutils/issues/2873
This commit is contained in:
Jan Scheer 2022-05-16 22:10:27 +02:00
parent 59827bca1a
commit 5aee95b4e5
No known key found for this signature in database
GPG key ID: C62AD4C29E2B9828
2 changed files with 22 additions and 10 deletions

View file

@ -9,7 +9,9 @@
*/ */
#[cfg(unix)] #[cfg(unix)]
pub use self::unix::{stdin_is_pipe_or_fifo, supports_pid_checks, Pid, ProcessChecker}; pub use self::unix::{
stdin_is_bad_fd, stdin_is_pipe_or_fifo, supports_pid_checks, Pid, ProcessChecker,
};
#[cfg(windows)] #[cfg(windows)]
pub use self::windows::{supports_pid_checks, Pid, ProcessChecker}; pub use self::windows::{supports_pid_checks, Pid, ProcessChecker};

View file

@ -51,7 +51,8 @@ fn get_errno() -> i32 {
pub fn stdin_is_pipe_or_fifo() -> bool { pub fn stdin_is_pipe_or_fifo() -> bool {
let fd = stdin().lock().as_raw_fd(); let fd = stdin().lock().as_raw_fd();
fd >= 0 // GNU tail checks fd >= 0 // GNU tail checks fd >= 0
fd >= 0
&& match fstat(fd) { && match fstat(fd) {
Ok(stat) => { Ok(stat) => {
let mode = stat.st_mode as libc::mode_t; let mode = stat.st_mode as libc::mode_t;
@ -61,3 +62,12 @@ pub fn stdin_is_pipe_or_fifo() -> bool {
Err(err) => panic!("{}", err), Err(err) => panic!("{}", err),
} }
} }
// FIXME: Detect a closed file descriptor, e.g.: `tail <&-`
pub fn stdin_is_bad_fd() -> bool {
let fd = stdin().as_raw_fd();
// this is never `true`, even with `<&-` because stdlib is reopening fds as /dev/null
// see also: https://github.com/uutils/coreutils/issues/2873
// (gnu/tests/tail-2/follow-stdin.sh fails because of this)
unsafe { libc::fcntl(fd, libc::F_GETFD) == -1 && get_errno() == libc::EBADF }
}