mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-27 11:07:44 +00:00
tail: Add gnu's warning when following stdin is ineffective. If no pid support set to 0 in Observer.
This commit is contained in:
parent
d57545d09c
commit
2dc8a1b55e
6 changed files with 37 additions and 16 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -2984,6 +2984,7 @@ dependencies = [
|
|||
name = "uu_tail"
|
||||
version = "0.0.16"
|
||||
dependencies = [
|
||||
"atty",
|
||||
"clap",
|
||||
"libc",
|
||||
"memchr",
|
||||
|
|
|
@ -22,6 +22,7 @@ memchr = "2.5.0"
|
|||
notify = { version = "=5.0.0", features=["macos_kqueue"]}
|
||||
uucore = { version=">=0.0.16", package="uucore", path="../../uucore", features=["ringbuffer", "lines"] }
|
||||
same-file = "1.0.6"
|
||||
atty = "0.2"
|
||||
|
||||
[target.'cfg(windows)'.dependencies]
|
||||
windows-sys = { version = "0.42.0", default-features = false, features = ["Win32_System_Threading", "Win32_Foundation"] }
|
||||
|
|
|
@ -7,8 +7,10 @@
|
|||
|
||||
use crate::paths::Input;
|
||||
use crate::{parse, platform, Quotable};
|
||||
use atty::Stream;
|
||||
use clap::crate_version;
|
||||
use clap::{parser::ValueSource, Arg, ArgAction, ArgMatches, Command};
|
||||
use same_file::Handle;
|
||||
use std::collections::VecDeque;
|
||||
use std::ffi::OsString;
|
||||
use std::time::Duration;
|
||||
|
@ -120,11 +122,6 @@ pub enum VerificationResult {
|
|||
NoOutput,
|
||||
}
|
||||
|
||||
pub enum CheckResult {
|
||||
Ok,
|
||||
NoPidSupport,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct Settings {
|
||||
pub follow: Option<FollowMode>,
|
||||
|
@ -202,6 +199,7 @@ impl Settings {
|
|||
format!("invalid PID: {}", pid_str.quote()),
|
||||
));
|
||||
}
|
||||
|
||||
settings.pid = pid;
|
||||
}
|
||||
Err(e) => {
|
||||
|
@ -243,7 +241,11 @@ impl Settings {
|
|||
self.inputs.iter().any(|input| input.is_stdin())
|
||||
}
|
||||
|
||||
pub fn check_warnings(&self) -> CheckResult {
|
||||
pub fn num_inputs(&self) -> usize {
|
||||
self.inputs.len()
|
||||
}
|
||||
|
||||
pub fn check_warnings(&self) {
|
||||
if self.retry {
|
||||
if self.follow.is_none() {
|
||||
show_warning!("--retry ignored; --retry is useful only when following");
|
||||
|
@ -257,11 +259,24 @@ impl Settings {
|
|||
show_warning!("PID ignored; --pid=PID is useful only when following");
|
||||
} else if !platform::supports_pid_checks(self.pid) {
|
||||
show_warning!("--pid=PID is not supported on this system");
|
||||
return CheckResult::NoPidSupport;
|
||||
}
|
||||
}
|
||||
|
||||
CheckResult::Ok
|
||||
if self.follow.is_some() && self.has_stdin() {
|
||||
let blocking_stdin = self.pid == 0
|
||||
&& self.follow == Some(FollowMode::Descriptor)
|
||||
&& self.num_inputs() == 1
|
||||
&& Handle::stdin().map_or(false, |handle| {
|
||||
handle
|
||||
.as_file()
|
||||
.metadata()
|
||||
.map_or(false, |meta| !meta.is_file())
|
||||
});
|
||||
|
||||
if !blocking_stdin && atty::is(Stream::Stdin) {
|
||||
show_warning!("following standard input indefinitely is ineffective");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn verify(&self) -> VerificationResult {
|
||||
|
|
|
@ -107,6 +107,12 @@ impl Observer {
|
|||
files: FileHandling,
|
||||
pid: platform::Pid,
|
||||
) -> Self {
|
||||
let pid = if platform::supports_pid_checks(pid) {
|
||||
pid
|
||||
} else {
|
||||
0
|
||||
};
|
||||
|
||||
Self {
|
||||
retry,
|
||||
follow,
|
||||
|
|
|
@ -42,12 +42,7 @@ use uucore::{show, show_error};
|
|||
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||
let settings = parse_args(args)?;
|
||||
|
||||
let mut observer = Observer::from(&settings);
|
||||
|
||||
match settings.check_warnings() {
|
||||
args::CheckResult::NoPidSupport => observer.pid = 0,
|
||||
args::CheckResult::Ok => {}
|
||||
}
|
||||
settings.check_warnings();
|
||||
|
||||
match settings.verify() {
|
||||
args::VerificationResult::CannotFollowStdinByName => {
|
||||
|
@ -62,11 +57,12 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
|||
args::VerificationResult::Ok => {}
|
||||
}
|
||||
|
||||
uu_tail(&settings, observer)
|
||||
uu_tail(&settings)
|
||||
}
|
||||
|
||||
fn uu_tail(settings: &Settings, mut observer: Observer) -> UResult<()> {
|
||||
fn uu_tail(settings: &Settings) -> UResult<()> {
|
||||
let mut printer = HeaderPrinter::new(settings.verbose, true);
|
||||
let mut observer = Observer::from(settings);
|
||||
|
||||
observer.start(settings)?;
|
||||
// Do an initial tail print of each path's content.
|
||||
|
|
|
@ -19,3 +19,5 @@ pub static BACKEND: &str = "kqueue";
|
|||
#[cfg(target_os = "windows")]
|
||||
pub static BACKEND: &str = "ReadDirectoryChanges";
|
||||
pub static FD0: &str = "/dev/fd/0";
|
||||
pub static IS_A_DIRECTORY: &str = "Is a directory";
|
||||
pub static DEV_TTY: &str = "/dev/tty";
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue