Collin Funk <[email protected]> writes:

> Reminds me of bug 79407. I'll have a look at a fix and adding a test.
>
> Here is how it behaved in some older versions vs. current:
>
>     $ mkdir -p directory && touch file{1,2,3} directory/file{1,2,3}
>     $ diff-3.5 --to-file=directory file1 file2 file3
>     $ echo $?
>     0
>     $ diff-3.10 --to-file=directory file1 file2 file3
>     $ echo $?
>     0
>     $ diff-current --to-file=directory file1 file2 file3
>     diff-current: directory: No such file or directory
>     diff-current: directory: No such file or directory
>     2
>
> Thanks,
> Collin
>
> [1] https://debbugs.gnu.org/cgi/bugreport.cgi?bug=79407

Hey Paul, can you take a look at this one?

I have bisected it to this commit:

commit ce65fcbeec251c952df2788a8b6c4131c46e7cea
Author:     Paul Eggert <[email protected]>
AuthorDate: Sun Jul 30 17:04:17 2023 -0700
Commit:     Paul Eggert <[email protected]>
CommitDate: Sat Aug 5 11:01:41 2023 -0700

    diff: avoid a race when opening files
    
    * src/diff.c (O_PATHSEARCH): New constant.
    (compare_files): Prefer openat+fstat to fstatat+openat,
    as it avoids a race and should be a bit faster.

Here is what I see from strace:

    $ strace diff --to-file=directory file1 file2 file3 2>&1 | grep ^openat
    [...]
    openat(AT_FDCWD, "file1", O_RDONLY|O_CLOEXEC) = 3
    openat(AT_FDCWD, "directory", O_RDONLY|O_CLOEXEC) = 4
    openat(4, "file1", O_RDONLY|O_CLOEXEC)  = 5
    openat(AT_FDCWD, "file2", O_RDONLY|O_CLOEXEC) = 3
    openat(4, "directory", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or 
directory)
    [...]
    openat(AT_FDCWD, "file3", O_RDONLY|O_CLOEXEC) = 3
    openat(4, "directory", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or 
directory)

So it looks like we set the file descriptor of NOPARENT to the file
descriptor of "directory". But we do not give openat the correct name.

The code is quite complex, so I feel like you will have an easier time
coming up with the correct fix.

Collin



Reply via email to