diff --git a/src/uu/tail/Cargo.toml b/src/uu/tail/Cargo.toml index e39b575ad..6462fa285 100644 --- a/src/uu/tail/Cargo.toml +++ b/src/uu/tail/Cargo.toml @@ -33,6 +33,9 @@ notify = { workspace = true } [target.'cfg(unix)'.dependencies] rustix = { workspace = true, features = ["fs", "process"] } +[target.'cfg(any(target_os = "linux", target_os = "android"))'.dependencies] +uucore = { workspace = true, features = ["pipes"] } + [target.'cfg(windows)'.dependencies] windows-sys = { workspace = true, features = [ "Win32_System_Threading", diff --git a/src/uu/tail/src/tail.rs b/src/uu/tail/src/tail.rs index 509a5619d..80250776f 100644 --- a/src/uu/tail/src/tail.rs +++ b/src/uu/tail/src/tail.rs @@ -575,17 +575,26 @@ fn unbounded_tail(reader: &mut BufReader, settings: &Settings) -> UR Ok(()) } -fn print_target_section(file: &mut R, limit: Option) -> UResult<()> -where - R: Read + ?Sized, -{ - // Print the target section of the file. +// Print the target section of the file +fn print_target_section< + #[cfg(any(target_os = "linux", target_os = "android"))] R: Read + rustix::fd::AsFd, + #[cfg(not(any(target_os = "linux", target_os = "android")))] R: Read + ?Sized, +>( + file: &mut R, + limit: Option, +) -> UResult<()> { let stdout = stdout(); let mut stdout = stdout.lock(); if let Some(limit) = limit { let mut reader = file.take(limit); io::copy(&mut reader, &mut stdout)?; } else { + // zero-copy fast-path + #[cfg(any(target_os = "linux", target_os = "android"))] + if uucore::pipes::splice_unbounded_broker(file, &mut stdout)? { + io::copy(file, &mut stdout)?; + } + #[cfg(not(any(target_os = "linux", target_os = "android")))] io::copy(file, &mut stdout)?; } Ok(())