From 9a6c7d3f6ea7c328e7760458b18fe6dfc6f8806f Mon Sep 17 00:00:00 2001
From: Paul Eggert
Date: Tue, 15 Aug 2017 15:53:50 -0700
Subject: [PATCH 1/2] rename: document+test NetBSD rename
Test failure reported by Bruno Haible in:
http://lists.gnu.org/archive/html/bug-gnulib/2017-08/msg00104.html
This is an area where NetBSD is better-behaved than POSIX,
so allow the NetBSD behavior in tests.
* doc/posix-functions/rename.texi:
* doc/posix-functions/renameat.texi: Document NetBSD behavior.
* tests/test-rename.h (test_rename): Allow NetBSD behavior.
---
ChangeLog | 11 +++++++++++
doc/posix-functions/rename.texi | 10 ++++++++++
doc/posix-functions/renameat.texi | 10 ++++++++++
tests/test-rename.h | 8 +++++++-
4 files changed, 38 insertions(+), 1 deletion(-)
diff --git a/ChangeLog b/ChangeLog
index b07825f..3d87c90 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2017-08-15 Paul Eggert
+
+ rename: document+test NetBSD rename
+ Test failure reported by Bruno Haible in:
+ http://lists.gnu.org/archive/html/bug-gnulib/2017-08/msg00104.html
+ This is an area where NetBSD is better-behaved than POSIX,
+ so allow the NetBSD behavior in tests.
+ * doc/posix-functions/rename.texi:
+ * doc/posix-functions/renameat.texi: Document NetBSD behavior.
+ * tests/test-rename.h (test_rename): Allow NetBSD behavior.
+
2017-08-15 Bruno Haible
renameat: Ensure declaration in on NetBSD.
diff --git a/doc/posix-functions/rename.texi b/doc/posix-functions/rename.texi
index 1e80656..b024b96 100644
--- a/doc/posix-functions/rename.texi
+++ b/doc/posix-functions/rename.texi
@@ -60,6 +60,16 @@ is counter-intuitive, so on some systems, @code{rename} fails with
@code{ENOTDIR} if either argument is a symlink with a trailing slash:
glibc, OpenBSD, Cygwin 1.7.
@item
+POSIX requires that @code{renameat} do nothing and return 0 if the
+source and destination are hard links to the same file. This behavior
+is counterintuitive, and on some systems @code{renameat} is a no-op in
+this way only if the source and destination identify the same
+directory entry. On these systems, for example, although renaming
address@hidden/f} to @file{f} is a no-op, renaming @file{f} to @file{g}
+deletes @file{f} when @file{f} and @file{g} are hard links to the same
+file:
+NetBSD.
address@hidden
After renaming a non-empty directory over an existing empty directory,
the old directory name is still visible through the @code{stat} function
for 30 seconds after the rename, on NFS file systems, on some platforms:
diff --git a/doc/posix-functions/renameat.texi b/doc/posix-functions/renameat.texi
index ee01b89..dd97132 100644
--- a/doc/posix-functions/renameat.texi
+++ b/doc/posix-functions/renameat.texi
@@ -39,6 +39,16 @@ is counter-intuitive, so on some systems, @code{renameat} fails with
@code{ENOTDIR} if either argument is a symlink with a trailing slash:
glibc, OpenBSD, Cygwin 1.7.
@item
+POSIX requires that @code{renameat} do nothing and return 0 if the
+source and destination are hard links to the same file. This behavior
+is counterintuitive, and on some systems @code{renameat} is a no-op in
+this way only if the source and destination identify the same
+directory entry. On these systems, for example, although renaming
address@hidden/f} to @file{f} is a no-op, renaming @file{f} to @file{g}
+deletes @file{f} when @file{f} and @file{g} are hard links to the same
+file:
+NetBSD.
address@hidden
After renaming a non-empty directory over an existing empty directory,
the old directory name is still visible through the @code{stat} function
for 30 seconds after the rename, on NFS file systems, on some platforms:
diff --git a/tests/test-rename.h b/tests/test-rename.h
index 93a1041..010d58d 100644
--- a/tests/test-rename.h
+++ b/tests/test-rename.h
@@ -522,7 +522,13 @@ test_rename (int (*func) (char const *, char const *), bool print)
{ /* File onto hard link. */
ASSERT (func (BASE "file", BASE "file2") == 0);
memset (&st, 0, sizeof st);
- ASSERT (stat (BASE "file", &st) == 0);
+ if (stat (BASE "file", &st) != 0)
+ {
+ /* This can happen on NetBSD. */
+ ASSERT (errno == ENOENT);
+ ASSERT (link (BASE "file2", BASE "file") == 0);
+ ASSERT (stat (BASE "file", &st) == 0);
+ }
ASSERT (st.st_size == 2);
memset (&st, 0, sizeof st);
ASSERT (stat (BASE "file2", &st) == 0);
--
2.7.4