Just to expand a little on Paul's response

On Tue, 16 Sept 2025 at 10:14, Paul Eggert <egg...@cs.ucla.edu> wrote:

> > 2. The other odd thing in the trace is that there are some kind of odd
> >     shenanigans going on with the two identical binary files, and a
> >     third temporary file that cp makes and then removes.
>

The point is that they're not *supposed* to be "identical binaries";
they're supposed to be multiple names for ONE file, because you specified
--preserve=all, which includes replicating the original pattern of (hard)
links in the target.


> >     I don't really
> >     follow the logic of the series of "linkat"s, "renameat"s, and
> >     "unlinkat"s around lines 70-80 of the trace, but while I could
> >     accept that they're somehow useful,



The "link" and "linkat" syscalls won't overwrite an existing target, as
this line shows in the strace output:

linkat(3, "./build-script-build", 3,
"./build_script_build-ed34004021de38b5", 0) = -1 EEXIST (File exists)


To work around this, it follows up this sequence:

linkat(3, "./build-script-build", 3, "./CuYCWUCU", 0) = 0
renameat(3, "./CuYCWUCU", 3, "./build_script_build-ed34004021de38b5") = 0


This works because the "rename" & "renameat" syscalls *will* overwrite a
target, and moreover, they guarantee atomicity while doing so (though
that's arguably not relevant here).

(You might like to submit a Linux kernel feature request to implement an
extra option flag for 'linkat' to do the same, perhaps AT_REPLACE.)

I have to admit I'm a bit puzzled by

unlinkat(3, "./CuYCWUCU", 0)            = 0

which would appear to be successfully removing a filename that no longer
exists.

>     the trace doesn't show any equivalent writes to the target
> >     directory, only the ones in the source directory


Note that all the "*at" syscalls above reference filedescriptor 3, which
was obtained earlier:

openat(AT_FDCWD, "/home/kye/test", O_RDONLY|O_PATH|O_DIRECTORY) = 3


meaning, they're all relative to /home/kye/test. This contrasts with the
ones that use 'AT_FDCWD' which treats relative paths as relative to the
calling process's cwd.

-Martin

Reply via email to