`pax -rwl` doesn't correctly set mtime on directories

Number:rdar://FB8957230 Date Originated:2020 Dec 30
Status: Resolved:
Product:macos Product Version:11.0.1
Classification:bug Reproducible:yes
1. Create a directory containing a file:

  % mkdir foo
  % touch foo/file

2. Copy that directory to another directory using `rm -rf bar && mkdir bar && cd foo && pax -rwl . ../bar`:

  % (rm -rf bar && mkdir bar && cd foo && pax -rwl . ../bar)

3. Compare timestamps on both the directory (!) and the file. (`pax -p` copies mtime by default, see `man pax` under the `-p` flag.)

  % stat -f '%N %Fm' foo
  foo 1609297230.485880489
  % stat -f '%N %Fm' foo/*
  foo/file 1609294944.907726636

  % stat -f '%N %Fm' bar
  bar 1609297230.000000000
  % stat -f '%N %Fm' bar/file
  bar/file 1609294944.907726636

Expected: The mtimes on both file and directory match.
Actual: The mtime on file matches (but only because it's a hardlink, without `-l` it's wrong too). The mtime on the directory loses its fractional part.

This is a problem for mtime-based build systems. They'll think that the output of the copy has an older timestamp than the input and will re-run the copy on every build. Ninja 1.9+ (https://ninja-build.org/) is an example of a build system that reads high-resolution timestamps and that gets confused by this.

See https://github.com/nico/hack/blob/master/notes/copydir.md for some background around this bug report.

This reproduces on macOS 10.15.7 and macOS 11.0.1.


Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!