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