Skip to content

tee: use splice if and only if fadvice failed - #15894

Closed
oech3 wants to merge 1 commit into
uutils:mainfrom
oech3:tee-fadv
Closed

oech3 wants to merge 1 commit into
uutils:mainfrom
oech3:tee-fadv

Conversation

@oech3

@oech3 oech3 commented Oct 27, 2026 •

Copy link
Copy Markdown
Contributor

Closes #15803

The provider_cmd file | tee out case should be provider_cmd's responsibility.
i.e. we should consider that cat is bug-compat with GNU and wait GNU's response about cat file | tee out case. It is not something tee sould care about.

Performance for tee<file can be improved using memfd later.

@codspeed

codspeed Bot commented Oct 27, 2026 •

Copy link
Copy Markdown

Merging this PR will degrade performance by 5.21%

2 warnings

⚠️ 1 benchmark is dominated by system calls

System calls cannot be simulated consistently and are left out of the measure. The reported value understates the real cost. Switch to the Walltime instrument to measure them.

Learn more about system calls

See affected benchmarks

⚠️ Base and head ran on different runner types

Some benchmarks with significant performance changes were compared across different runner types, so the changes might not come from the code. Run base and head on the same runner type, or use CodSpeed Macro Runners for more stable results.

Learn more about Macro Runners

Open the report in CodSpeed to investigate

❌ 1 regressed benchmark
✅ 1 untouched benchmark
⏩ 470 skipped benchmarks1

Warning

Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Mode Benchmark BASE HEAD Efficiency
❌ CPU Simulation tee_stdin_file[10000000] 359.1 µs 378.9 µs -5.21%

Tip

Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.


Comparing oech3:tee-fadv (c63ed56) with main (c1f1728)

Open in CodSpeed

Footnotes

  1. 470 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports. ↩

@github-actions

Copy link
Copy Markdown

GNU testsuite comparison:

GNU test failed: tests/tee/write-eagain. tests/tee/write-eagain is passing on 'main'. Maybe you have to rebase?

@xtqqczze

Copy link
Copy Markdown
Collaborator

The fadvise check at tee.rs:167 avoids the fast path for file stdin when the advice succeeds, but it does not make the path safe for pipe stdin. A pipe may carry page references from a producer using vmsplice or a zero-copy utility such as cat. An advice failure also isn’t a reliable guarantee that the input is not a file.

@oech3

oech3 commented Oct 27, 2026 •

Copy link
Copy Markdown
Contributor Author

The case must be considered as producer's bug, not a tee's bug. Also no need to care about something like strace injection for fadvise.

@oech3

oech3 commented Oct 27, 2026 •

Copy link
Copy Markdown
Contributor Author

Also using zero-copy by producer itself is not a problem. yes provides source from provate surce.
We should consider that cat has a bug (which is bug-compat with GNU) for cat file case.

For pv, user should just see pv's manpage.

@oech3

oech3 commented Oct 27, 2026 •

Copy link
Copy Markdown
Contributor Author

An advice failure also isn’t a reliable guarantee that the input is not a file.

I think you are talking about ESPIPE, but actually, EINVAL because of the input with missing support of page caches is also fine.

@xtqqczze

Copy link
Copy Markdown
Collaborator

The case must be considered as producer's bug

I don’t think this is correct; tee must handle the input it receives correctly, regardless of how the producer supplies it.

@oech3

oech3 commented Oct 27, 2026

Copy link
Copy Markdown
Contributor Author

I don't agree with you. If producer_cmd file | tee is broken, produer_cmd itself is already broken.
There is no reason to fix broken source.

@xtqqczze

Copy link
Copy Markdown
Collaborator

I disagree. tee must handle input correctly, regardless of where it comes from.

@oech3

oech3 commented Oct 27, 2026

Copy link
Copy Markdown
Contributor Author

vmsplice's manpage say's don't edit after sending. If producer viorated it, it is producer's fault. We should do same things for other APIs.

Comment thread src/uu/tee/src/tee.rs
@oech3

oech3 commented Oct 27, 2026

Copy link
Copy Markdown
Contributor Author

I don't like to repeat same things, but fixing already evil source as receiver side does not improve security.

@xtqqczze

Copy link
Copy Markdown
Collaborator

We must guarantee the following, per POSIX:

The tee utility shall copy standard input to standard output, making a copy in zero or more files

Unless we can guarantee the source is immutable, I think we must copy the data before calling pipes::tee to ensure correctness.

@oech3

oech3 commented Oct 27, 2026

Copy link
Copy Markdown
Contributor Author

While I "strongly" think that this is producer's responsibility., I prefer #15854 if we needed to doubt it.

However, we should consider this after GNU decided to make cat reliable and use memfd also for one output case too.

@oech3 oech3 closed this Oct 27, 2026
@oech3
oech3 deleted the tee-fadv branch October 27, 2026 04:26
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.

tee: zero-copy lets stdout and FILE differ if input changes after tee exits

2 participants