From dd311b294b73dd3ca826035183562d5bf858d92e Mon Sep 17 00:00:00 2001 From: Terts Diepraam Date: Fri, 28 Jan 2022 18:17:40 +0100 Subject: [PATCH] wc: fix counting files from pseudo-filesystem --- .vscode/cspell.dictionaries/jargon.wordlist.txt | 2 ++ src/uu/wc/src/count_fast.rs | 8 +++++++- tests/by-util/test_wc.rs | 10 ++++++++++ 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/.vscode/cspell.dictionaries/jargon.wordlist.txt b/.vscode/cspell.dictionaries/jargon.wordlist.txt index 4e5f11e8d..99d6c5e40 100644 --- a/.vscode/cspell.dictionaries/jargon.wordlist.txt +++ b/.vscode/cspell.dictionaries/jargon.wordlist.txt @@ -37,6 +37,8 @@ exponentiate eval falsey fileio +filesystem +filesystems flamegraph fullblock getfacl diff --git a/src/uu/wc/src/count_fast.rs b/src/uu/wc/src/count_fast.rs index e4f6be6c1..4515cd3d7 100644 --- a/src/uu/wc/src/count_fast.rs +++ b/src/uu/wc/src/count_fast.rs @@ -80,7 +80,13 @@ pub(crate) fn count_bytes_fast(handle: &mut T) -> (usize, Opti if let Ok(stat) = stat::fstat(fd) { // If the file is regular, then the `st_size` should hold // the file's size in bytes. - if (stat.st_mode & S_IFREG) != 0 { + // If stat.st_size = 0 then + // - either the size is 0 + // - or the size is unknown. + // The second case happens for files in pseudo-filesystems. For + // example with /proc/version and /sys/kernel/profiling. So, + // if it is 0 we don't report that and instead do a full read. + if (stat.st_mode & S_IFREG) != 0 && stat.st_size > 0 { return (stat.st_size as usize, None); } #[cfg(any(target_os = "linux", target_os = "android"))] diff --git a/tests/by-util/test_wc.rs b/tests/by-util/test_wc.rs index eabaf58eb..5c4763f99 100644 --- a/tests/by-util/test_wc.rs +++ b/tests/by-util/test_wc.rs @@ -1,3 +1,6 @@ +#[cfg(all(unix, not(target_os = "macos")))] +use pretty_assertions::assert_ne; + use crate::common::util::*; // spell-checker:ignore (flags) lwmcL clmwL ; (path) bogusfile emptyfile manyemptylines moby notrailingnewline onelongemptyline onelongword weirdchars @@ -235,3 +238,10 @@ fn test_read_from_nonexistent_file() { .stderr_contains(MSG) .stdout_is(""); } + +#[test] +#[cfg(all(unix, not(target_os = "macos")))] +fn test_files_from_pseudo_filesystem() { + let result = new_ucmd!().arg("-c").arg("/proc/version").succeeds(); + assert_ne!(result.stdout_str(), "0 /proc/version\n"); +}