Skip to content

wc: seek through redirected regular input for byte counts - #15492

Open
limadog9 wants to merge 1 commit into
uutils:mainfrom
limadog9:fix/wc-seek-stdin-byte-count-11610
Open

limadog9 wants to merge 1 commit into
uutils:mainfrom
limadog9:fix/wc-seek-stdin-byte-count-11610

Conversation

@limadog9

Copy link
Copy Markdown
Contributor

Use the current file offset and metadata for byte counts on regular input, advancing stdin to the counted end. Retain final-block probing for pseudo-files and preserve counted bytes when splice falls back.

Regression coverage includes partial offsets, repeated '-' operands, EOF, and page-aligned files. All 60 wc integration tests pass.

Closes #11610.

Comment thread tests/by-util/test_wc.rs Outdated

#[test]
#[cfg(unix)]
fn test_byte_count_redirected_file_position() {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a performance issue instead of a bug. So test is not needed.

@limadog9
limadog9 force-pushed the fix/wc-seek-stdin-byte-count-11610 branch from f5ebe5b to 6370450 Compare October 18, 2026 18:39
// another process sharing stdin sees EOF.
if (stat.st_mode as libc::mode_t & libc::S_IFREG) != 0
&& stat.st_size > 0
&& let Ok(position) = rustix::fs::seek(&handle, SeekFrom::Current(0))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this now changes the result of ( head -c1; wc -c ) < file, not only the speed.
could you please keep one test for the partial offset case? the old code had a full comment just to protect it

@sylvestre

Copy link
Copy Markdown
Contributor

The description mentions regression tests, but the diff no longer has any. Please add back at least the partial offset one. Thanks


if let Ok(n) = file.seek(SeekFrom::Start(offset as u64)) {
byte_count = n as usize;
let block_size = stat.st_blksize as u64;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the comment explaining why this allow is needed was removed, please keep a short version

@limadog9
limadog9 force-pushed the fix/wc-seek-stdin-byte-count-11610 branch from 6370450 to 3a352d5 Compare October 18, 2026 22:36
Comment thread tests/by-util/test_wc.rs
.set_stdin(shared)
.succeeds()
.stdout_only("5\n");
assert_eq!(input.stream_position().unwrap(), 6);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could you please also add a test for wc -c - - with a file as stdin? it should print the size then 0
the description still mentions it, along with the EOF and page-aligned tests

@limadog9
limadog9 force-pushed the fix/wc-seek-stdin-byte-count-11610 branch from 3a352d5 to 06643d6 Compare October 19, 2026 19:37
Comment thread src/uu/wc/src/countable.rs Outdated
@@ -19,7 +19,6 @@ use std::os::fd::{AsFd, AsRawFd};
pub trait WordCountable: AsFd + AsRawFd + Read {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as_raw_fd() isn't called anymore, could AsRawFd be dropped from the bound?

@limadog9
limadog9 force-pushed the fix/wc-seek-stdin-byte-count-11610 branch from 06643d6 to ebcfbb5 Compare October 23, 2026 02:06
@github-actions

Copy link
Copy Markdown

Binary size comparison:

Individual binary size comparison VS main (threshold: >=5% AND >=4 KB).

Total size of compared binaries: 155.04 MB (-308 KB, -0.19%)

Significant per-binary changes:
  date     2.61 MB ->    2.30 MB  (-316 KB, -11.81%)

Comment thread tests/by-util/test_wc.rs
#[rstest::rstest]
#[case::partial(6, 1)]
#[case::at_eof(6, 6)]
#[case::page_aligned(4096, 0)]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could you please add a page_aligned case with a non zero offset too? nothing covers the .max(position) part

Use the current file offset and metadata for byte counts on regular
input, advancing stdin to the counted end. Retain final-block probing
for pseudo-files and preserve counted bytes when splice falls back.

Closes uutils#11610.
@limadog9
limadog9 force-pushed the fix/wc-seek-stdin-byte-count-11610 branch from ebcfbb5 to e0e5080 Compare October 24, 2026 14:30

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

wc: wc -c does not optimize stdin as input by metadata

3 participants