Hi,
dd has this final_op_was_seek edge case growing undersized stdout:
> strace -e trace=ftruncate dd if=/dev/zero count=4 conv=notrunc,sparse
> ftruncate(1, 2048) = -1 EPERM (Operation not permitted)
> dd: failed to truncate to 2048 bytes in output file 'standard
> output': Operation not permitted
> +++ exited with 1 +++
> # --version: dd (coreutils) 9.12
Man said:
> ’sparse’ [..] Be careful when using this conversion in conjunction
> with ‘conv=notrunc’
I was not careful ;) and surprised:
a) there is no of=, meaning the (POSIX?) compatibility assumption that
stdout does not need to support truncation still applies; and
b) there is conv=notrunc, meaning I was not exactly requesting
truncation. Quite the opposite.
Seems correct though. And I do not see a way to change it now while
maintaining documented behavior otherwise. Not like this happens
a lot in real life (I was playing with fuse; the most straightforward
reproducer is to deliberately fcntl F_SEAL_GROW stdout).. but maybe
document it for of= and conv=notrunc, sth. like:
+ ’notrunc’ Do not truncate the output file. This does not disable the
+ truncation that may be needed with ’conv=sparse’ to grow an undersized
+ output file.
.. plus: make the error clarify which kind of truncation it refers to?
- diagnose (errno, _("failed to truncate to %jd bytes"
+ diagnose (errno, _("failed to truncate (extend) to %jd bytes"
Ref: discussion on allowing notrunc+sparse was in bug#9157
MfG pjd