Hello maintainers,
I was trying out the new `--set-mtime-command` option in tar 1.35.90 and
ran into some behavior I couldn't explain: whatever timestamp my helper
command printed, tar either complained that the output didn't match my
format string, or quietly stored a completely wrong mtime.
After poking at it a bit, I went and read the code, and I think I found
the cause. In sys_exec_setmtime_script() (src/system.c), the loop that
reads the command's output advances the buffer length with the poll()
return value instead of the number of bytes read:
```
src/system.c:973 ssize_t nread = read (pfd.fd, buffer + buflen,
bufsize - buflen);
...
src/system.c:982 buflen += n;
```
`n` here is the return value of poll(), which is always 1 in this
single-fd loop, so it isn't the byte count -- that's `nread`. Once
xpalloc() has grown the buffer beyond one byte, a multi-byte read()
only bumps buflen by 1, and everything after the first byte gets
dropped. That explains what I was seeing: only the first character of
the command's output ever reaches strptime()/parse_datetime().
I checked current git master and the same line is still there
(src/system.c:996), so it looks like it affects master too.
A one-line change fixes it for me:
```
- buflen += n;
+ buflen += nread;
```
Steps to reproduce:
```
$ mkdir /tmp/bug && cd /tmp/bug
$ echo hello > f.txt
$ printf '#!/bin/sh\necho 1700000000\n' > mtime.sh && chmod +x mtime.sh
$ tar -cf a.tar --set-mtime-command="$PWD/mtime.sh" \
--set-mtime-format=%s f.txt
$ echo "exit=$?"
exit=0
$ tar --utc -tvf a.tar
-rw-rw-r-- user/user 6 1970-01-01 00:00 f.txt
```
The command prints 1700000000 (2023-11-14), but tar stores epoch 1
(1970-01-01) -- it kept only the first byte "1" -- and still exits 0,
so the wrong timestamp goes in silently.
With a human-readable format the same truncation shows up as an error
instead:
```
$ printf '#!/bin/sh\necho "2020-01-02 03:04:05"\n' > mtime.sh
$ tar -cf a.tar --set-mtime-command="$PWD/mtime.sh" \
--set-mtime-format="%Y-%m-%d %H:%M:%S" f.txt
tar: output from "...mtime.sh f.txt" does not satisfy format string: 2
tar: Exiting with failure status due to previous errors
```
(only the first byte "2" makes it through).
With the one-line change above, both cases work as I'd expect: the
first records 2023-11-14 and the second records 2020-01-02.
I built tar 1.35.90 from source on GNU/Linux to confirm all of this.
Hope this helps, and thanks for tar!
Best regards,
Xinting Zhou