From a37df18aae6c52fab2c7efebff28585e5365268e Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Wed, 24 Mar 2021 20:40:46 -0700 Subject: [PATCH] renameatu: work around macOS 11.2 renameatx_np bug * lib/renameatu.c (renameatu) [RENAME_EXCL]: Use lstatat test here too. --- ChangeLog | 5 +++++ lib/renameatu.c | 7 ++++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index b2004479a2..af9eb725cb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2021-03-24 Paul Eggert + + renameatu: work around macOS 11.2 renameatx_np bug + * lib/renameatu.c (renameatu) [RENAME_EXCL]: Use lstatat test here too. + 2021-03-22 Bruno Haible clean-temp-simple: Fix a rare memory leak. diff --git a/lib/renameatu.c b/lib/renameatu.c index c493a38dc1..38438a4ef1 100644 --- a/lib/renameatu.c +++ b/lib/renameatu.c @@ -122,18 +122,19 @@ renameatu (int fd1, char const *src, int fd2, char const *dst, | (flags & RENAME_NOREPLACE ? RENAME_EXCL : 0)); # endif -# if !defined RENAME_EXCL if ((flags & RENAME_NOREPLACE) != 0) { /* This has a race between the call to lstatat and the calls to - renameat below. */ + renameat below. This lstatat is needed even if RENAME_EXCL + is defined, because RENAME_EXCL is buggy on macOS 11.2: + renameatx_np (fd, "X", fd, "X", RENAME_EXCL) incorrectly + succeeds when X exists. */ if (lstatat (fd2, dst, &dst_st) == 0 || errno == EOVERFLOW) return errno_fail (EEXIST); if (errno != ENOENT) return -1; dst_found_nonexistent = true; } -# endif /* Let strace see any ENOENT failure. */ src_len = strlen (src); -- 2.39.5