Repository navigation
tee: handle short writes to stdout correctly #14981
Description
Activity
taken by @mattsu2020
Difference of used syscall is not a problem if the used syscall is an optional dependency.
We can patch GnuTests in this case to support our syscall.Difference of used syscall is not a problem if the used syscall is an optional dependency. We can patch GnuTests in this case to support our syscall.
Should we update the GNU test to use splice instead?
I think so. But it is bit tricky to the test meaningful for splice(2) path. I'd like to patch to fail splice path at fallback to write path at a moment.
It is done by adding
-e fault=splice.Reacted by mattsuWe could use named pipe with 1 byte remain to cause short-write. But it would be too complex.
I think it is impossible to do same strace test for
splice(2)sincestraceis a tool to modify returned value, not a len passed tosplice(2).I think it is impossible to do same strace test for
splice(2)sincestraceis a tool to modify returned value, not a len passed tosplice(2).How about changing the test to something like the following?
strace -qqq -o /dev/null --trace-fds=1 -e trace=write,splice \ -e fault=splice \ -e inject=write:retval=1:when=1..5 "$@"#14981 (comment) tests write code path only.
OK. So splice(2) and write(2) are very different.
- retval=1 for write(2) means write(2) returns 1 without actually writing.
So next read(2) consumes buffer. Then we lost "a".So we lost "a" by previousread(2). It is expected and used at GnuTests. - retval=1 for splice(2) means splice(2) returns 1 without actually sending. So pipe buffer is NOT changed. It is "correct" behaviour. Then we see "a" after all retval'ed call finished since it is still in pipe buffer.
Reacted by mattsu- retval=1 for write(2) means write(2) returns 1 without actually writing.
I fixed the previous comment about read.
tee does not correctly handle short writes to stdout when stdout is a regular file on Linux.
The GNU tee/short-write.sh test expects short writes to be retried until the remaining data is written, but the current implementation uses the splice path for regular-file stdout, bypassing the injected write(2) short writes.
We should ensure that short writes to regular-file stdout are handled correctly.
Related to #14705.