From: Bruno Haible <bruno@clisp.org>
To: bug-gnulib@gnu.org
Cc: "Martin Storsjö" <martin@martin.st>
Subject: renameatu: Fix test failures on macOS
Date: Sat, 02 Jan 2021 17:03:16 +0100 [thread overview]
Message-ID: <2292620.QaEihNl2m5@omega> (raw)
In-Reply-To: <alpine.DEB.2.23.453.2012011509530.4295@cone.martin.st>
On macOS 10.13, I'm seeing these test failures (for a long time already).
FAIL: test-renameat
===================
../../gltests/test-rename.h:619: assertion 'func (BASE "link2/", BASE "link2") == -1' failed
FAIL test-renameat (exit status: 134)
FAIL: test-renameatu
====================
../../gltests/test-rename.h:619: assertion 'func (BASE "link2/", BASE "link2") == -1' failed
FAIL test-renameatu (exit status: 134)
This was also reported by Martin Storsjö.
The situation is that config.h contains:
#define HAVE_RENAMEAT 1
/* #undef HAVE_RENAMEAT2 */
/* #undef RENAME_DEST_EXISTS_BUG */
/* #undef RENAME_HARD_LINK_BUG */
#define RENAME_TRAILING_SLASH_DEST_BUG 1
#define RENAME_TRAILING_SLASH_SOURCE_BUG 1
But the invocation of 'renameatx_np' right at the beginning of renameatu()
assumes that it works without bugs. Which it doesn't.
This patch fixes both test failures.
2021-01-02 Bruno Haible <bruno@clisp.org>
renameatu: Fix test failures on macOS.
Reported by Martin Storsjö <martin@martin.st> in
<https://lists.gnu.org/archive/html/bug-gnulib/2020-12/msg00003.html>.
* lib/renameatu.c (renameatu): Don't call renameatx_np right away.
Instead, treat it as a variant of renameat, with all possible bugs that
renameat might have.
diff --git a/lib/renameatu.c b/lib/renameatu.c
index 974d234..c493a38 100644
--- a/lib/renameatu.c
+++ b/lib/renameatu.c
@@ -86,14 +86,6 @@ renameatu (int fd1, char const *src, int fd2, char const *dst,
#elif defined SYS_renameat2
ret_val = syscall (SYS_renameat2, fd1, src, fd2, dst, flags);
err = errno;
-#elif defined RENAME_EXCL
- if (! (flags & ~(RENAME_EXCHANGE | RENAME_NOREPLACE)))
- {
- ret_val = renameatx_np (fd1, src, fd2, dst,
- ((flags & RENAME_EXCHANGE ? RENAME_SWAP : 0)
- | (flags & RENAME_NOREPLACE ? RENAME_EXCL : 0)));
- err = errno;
- }
#endif
if (! (ret_val < 0 && (err == EINVAL || err == ENOSYS || err == ENOTSUP)))
@@ -101,6 +93,9 @@ renameatu (int fd1, char const *src, int fd2, char const *dst,
#if HAVE_RENAMEAT
{
+# if defined RENAME_EXCL /* macOS */
+ unsigned int uflags;
+# endif
size_t src_len;
size_t dst_len;
char *src_temp = (char *) src;
@@ -112,33 +107,52 @@ renameatu (int fd1, char const *src, int fd2, char const *dst,
struct stat dst_st;
bool dst_found_nonexistent = false;
- if (flags != 0)
+ /* Check the flags. */
+# if defined RENAME_EXCL
+ /* We can support RENAME_EXCHANGE and RENAME_NOREPLACE. */
+ if (flags & ~(RENAME_EXCHANGE | RENAME_NOREPLACE))
+# else
+ /* RENAME_NOREPLACE is the only flag currently supported. */
+ if (flags & ~RENAME_NOREPLACE)
+# endif
+ return errno_fail (ENOTSUP);
+
+# if defined RENAME_EXCL
+ uflags = ((flags & RENAME_EXCHANGE ? RENAME_SWAP : 0)
+ | (flags & RENAME_NOREPLACE ? RENAME_EXCL : 0));
+# endif
+
+# if !defined RENAME_EXCL
+ if ((flags & RENAME_NOREPLACE) != 0)
{
- /* RENAME_NOREPLACE is the only flag currently supported. */
- if (flags & ~RENAME_NOREPLACE)
- return errno_fail (ENOTSUP);
- else
- {
- /* This has a race between the call to lstatat and the calls to
- renameat below. */
- if (lstatat (fd2, dst, &dst_st) == 0 || errno == EOVERFLOW)
- return errno_fail (EEXIST);
- if (errno != ENOENT)
- return -1;
- dst_found_nonexistent = true;
- }
+ /* This has a race between the call to lstatat and the calls to
+ renameat below. */
+ 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);
dst_len = strlen (dst);
if (!src_len || !dst_len)
+# if defined RENAME_EXCL
+ return renameatx_np (fd1, src, fd2, dst, uflags);
+# else
return renameat (fd1, src, fd2, dst);
+# endif
src_slash = src[src_len - 1] == '/';
dst_slash = dst[dst_len - 1] == '/';
if (!src_slash && !dst_slash)
+# if defined RENAME_EXCL
+ return renameatx_np (fd1, src, fd2, dst, uflags);
+# else
return renameat (fd1, src, fd2, dst);
+# endif
/* Presence of a trailing slash requires directory semantics. If
the source does not exist, or if the destination cannot be turned
@@ -211,7 +225,11 @@ renameatu (int fd1, char const *src, int fd2, char const *dst,
on Solaris, since all other systems either lack renameat or honor
trailing slash correctly. */
+# if defined RENAME_EXCL
+ ret_val = renameatx_np (fd1, src_temp, fd2, dst_temp, uflags);
+# else
ret_val = renameat (fd1, src_temp, fd2, dst_temp);
+# endif
rename_errno = errno;
goto out;
out:
next prev parent reply other threads:[~2021-01-02 16:03 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-12-01 13:14 Issues with posix functions on modern macOS/Xcode Martin Storsjö
2020-12-01 13:50 ` Martin Storsjö
2020-12-01 18:58 ` Bruno Haible
2020-12-02 18:56 ` Bruno Haible
2021-01-02 20:43 ` Bruno Haible
2021-03-21 2:57 ` Bruno Haible
2021-03-21 13:58 ` Bruno Haible
2020-12-02 21:52 ` strsignal on macOS Bruno Haible
2020-12-03 20:59 ` fprintf-posix " Bruno Haible
2020-12-04 23:24 ` utime " Bruno Haible
2021-01-02 16:03 ` Bruno Haible [this message]
2021-01-02 18:06 ` utimens: Fix test failures " Bruno Haible
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://lists.gnu.org/mailman/listinfo/bug-gnulib
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=2292620.QaEihNl2m5@omega \
--to=bruno@clisp.org \
--cc=bug-gnulib@gnu.org \
--cc=martin@martin.st \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).