1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-07-27 19:17:43 +00:00

Merge pull request #3706 from anastygnome/tail_refactor

Rework tail plateform module to tackle #2873
This commit is contained in:
Sylvestre Ledru 2022-08-14 17:53:23 +02:00 committed by GitHub
commit 38a64bdc2e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 29 additions and 33 deletions

View file

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

View file

@ -8,16 +8,12 @@
* file that was distributed with this source code. * file that was distributed with this source code.
*/ */
// spell-checker:ignore (ToDO) stdlib // spell-checker:ignore (ToDO) stdlib, ISCHR, GETFD
// spell-checker:ignore (options) GETFD EPERM ENOSYS // spell-checker:ignore (options) EPERM, ENOSYS
use std::io::{stdin, Error};
use std::os::unix::prelude::AsRawFd;
use libc::S_IFCHR;
use nix::sys::stat::fstat; use nix::sys::stat::fstat;
use std::io::Error;
use libc::{S_IFIFO, S_IFSOCK};
pub type Pid = libc::pid_t; pub type Pid = libc::pid_t;
@ -49,26 +45,19 @@ pub fn supports_pid_checks(pid: self::Pid) -> bool {
fn get_errno() -> i32 { fn get_errno() -> i32 {
Error::last_os_error().raw_os_error().unwrap() Error::last_os_error().raw_os_error().unwrap()
} }
#[inline]
pub fn stdin_is_pipe_or_fifo() -> bool { pub fn stdin_is_pipe_or_fifo() -> bool {
let fd = stdin().lock().as_raw_fd(); // IFCHR means the file (stdin) is a character input device, which is the case of a terminal.
// GNU tail checks fd >= 0 // We just need to check if stdin is not a character device here, because we are not interested
fd >= 0 // in the type of stdin itself.
&& match fstat(fd) { fstat(libc::STDIN_FILENO).map_or(false, |file| file.st_mode as libc::mode_t & S_IFCHR == 0)
Ok(stat) => {
let mode = stat.st_mode as libc::mode_t;
// NOTE: This is probably not the most correct way to check this
(mode & S_IFIFO != 0) || (mode & S_IFSOCK != 0)
}
Err(err) => panic!("{}", err),
}
} }
//pub fn stdin_is_bad_fd() -> bool {
// FIXME: Detect a closed file descriptor, e.g.: `tail <&-` // 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 Rust's stdlib is reopening fds as /dev/null // this is never `true`, even with `<&-` because Rust's stdlib is reopening fds as /dev/null
// see also: https://github.com/uutils/coreutils/issues/2873 // see also: https://github.com/uutils/coreutils/issues/2873
// (gnu/tests/tail-2/follow-stdin.sh fails because of this) // (gnu/tests/tail-2/follow-stdin.sh fails because of this)
unsafe { libc::fcntl(fd, libc::F_GETFD) == -1 && get_errno() == libc::EBADF } // unsafe { libc::fcntl(fd, libc::F_GETFD) == -1 && get_errno() == libc::EBADF }
} //false
//}

View file

@ -11,7 +11,7 @@
// spell-checker:ignore (libs) kqueue // spell-checker:ignore (libs) kqueue
// spell-checker:ignore (acronyms) // spell-checker:ignore (acronyms)
// spell-checker:ignore (env/flags) // spell-checker:ignore (env/flags)
// spell-checker:ignore (jargon) tailable untailable // spell-checker:ignore (jargon) tailable untailable stdlib
// spell-checker:ignore (names) // spell-checker:ignore (names)
// spell-checker:ignore (shell/tools) // spell-checker:ignore (shell/tools)
// spell-checker:ignore (misc) // spell-checker:ignore (misc)
@ -1522,13 +1522,16 @@ pub fn stdin_is_pipe_or_fifo() -> bool {
.unwrap_or(false) .unwrap_or(false)
} }
} }
#[inline]
pub fn stdin_is_bad_fd() -> bool { pub fn stdin_is_bad_fd() -> bool {
#[cfg(unix)] // FIXME : Rust's 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)
//#[cfg(unix)]
{ {
platform::stdin_is_bad_fd() //platform::stdin_is_bad_fd()
} }
#[cfg(not(unix))] //#[cfg(not(unix))]
false false
} }