summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Blake <ebb9@byu.net>2009-11-09 10:44:08 -0700
committerEric Blake <ebb9@byu.net>2009-11-10 06:32:39 -0700
commit24208770c8721323060207c9be83dd24400678d3 (patch)
tree306747d3ceb847525de7ffb218de1b73fa389bf5
parentb0d3085924955e48a830dd1630989471f4bc57cb (diff)
downloadgnulib-24208770c8721323060207c9be83dd24400678d3.tar.gz
unlink, remove: detect FreeBSD bug
unlink("link-to-file/") mistakenly removed "file". * m4/unlink.m4 (gl_FUNC_UNLINK): Also detect FreeBSD bug with slash on symlink. * doc/posix-functions/unlink.texi (unlink): Document the bug. * doc/posix-functions/remove.texi (remove): Likewise. * tests/test-unlink.h (test_unlink): Enhance test. * tests/test-remove.c (main): Likewise. Signed-off-by: Eric Blake <ebb9@byu.net>
-rw-r--r--ChangeLog10
-rw-r--r--doc/posix-functions/remove.texi2
-rw-r--r--doc/posix-functions/unlink.texi4
-rw-r--r--m4/unlink.m416
-rw-r--r--tests/test-remove.c13
-rw-r--r--tests/test-unlink.h7
6 files changed, 43 insertions, 9 deletions
diff --git a/ChangeLog b/ChangeLog
index 599a2ab6ad..8d3dcea353 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2009-11-10 Eric Blake <ebb9@byu.net>
+
+ unlink, remove: detect FreeBSD bug
+ * m4/unlink.m4 (gl_FUNC_UNLINK): Also detect FreeBSD bug with
+ slash on symlink.
+ * doc/posix-functions/unlink.texi (unlink): Document the bug.
+ * doc/posix-functions/remove.texi (remove): Likewise.
+ * tests/test-unlink.h (test_unlink): Enhance test.
+ * tests/test-remove.c (main): Likewise.
+
2009-11-09 Eric Blake <ebb9@byu.net>
rename: detect FreeBSD bug
diff --git a/doc/posix-functions/remove.texi b/doc/posix-functions/remove.texi
index b3e3d1b1fb..83a8955c9b 100644
--- a/doc/posix-functions/remove.texi
+++ b/doc/posix-functions/remove.texi
@@ -11,7 +11,7 @@ Portability problems fixed by Gnulib:
@item
This function fails to reject trailing slashes on non-directories on
some platforms:
-Solaris 9.
+FreeBSD 7.2, Solaris 9.
@item
This function mistakenly removes a directory with
@code{remove("dir/./")} on some platforms:
diff --git a/doc/posix-functions/unlink.texi b/doc/posix-functions/unlink.texi
index 1df1e30b36..42b9e817e5 100644
--- a/doc/posix-functions/unlink.texi
+++ b/doc/posix-functions/unlink.texi
@@ -9,8 +9,8 @@ Gnulib module: unlink
Portability problems fixed by Gnulib:
@itemize
@item
-Some systems mistakenly succeed on @code{unlink("file/")}:
-GNU/Hurd, Solaris 9.
+Some systems mistakenly succeed on @code{unlink("link-to-file/")}:
+GNU/Hurd, FreeBSD 7.2, Solaris 9.
@end itemize
Portability problems not fixed by Gnulib:
diff --git a/m4/unlink.m4 b/m4/unlink.m4
index 626c3adf35..bed24665de 100644
--- a/m4/unlink.m4
+++ b/m4/unlink.m4
@@ -1,4 +1,4 @@
-# unlink.m4 serial 1
+# unlink.m4 serial 2
dnl Copyright (C) 2009 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
@@ -8,18 +8,26 @@ AC_DEFUN([gl_FUNC_UNLINK],
[
AC_REQUIRE([gl_AC_DOS])
AC_REQUIRE([gl_UNISTD_H_DEFAULTS])
- dnl Detect Solaris 9 bug.
+ dnl Detect Solaris 9 and FreeBSD 7.2 bug.
AC_CACHE_CHECK([whether unlink honors trailing slashes],
[gl_cv_func_unlink_works],
[touch conftest.file
+ # Assume that if we have lstat, we can also check symlinks.
+ if test $ac_cv_func_lstat = yes; then
+ ln -s conftest.file conftest.lnk
+ fi
AC_RUN_IFELSE(
[AC_LANG_PROGRAM(
[[#include <stdio.h>
#include <errno.h>
-]], [[return !unlink ("conftest.file/") || errno != ENOTDIR;]])],
+]], [[if (!unlink ("conftest.file/") || errno != ENOTDIR) return 1;
+#if HAVE_LSTAT
+ if (!unlink ("conftest.lnk/") || errno != ENOTDIR) return 2;
+#endif
+ ]])],
[gl_cv_func_unlink_works=yes], [gl_cv_func_unlink_works=no],
[gl_cv_func_unlink_works="guessing no"])
- rm -f conftest.file])
+ rm -f conftest.file conftest.lnk])
if test x"$gl_cv_func_unlink_works" != xyes; then
REPLACE_UNLINK=1
AC_LIBOBJ([unlink])
diff --git a/tests/test-remove.c b/tests/test-remove.c
index af5d01bc23..16bfe2f9b7 100644
--- a/tests/test-remove.c
+++ b/tests/test-remove.c
@@ -113,6 +113,19 @@ main (void)
ASSERT (S_ISLNK (st.st_mode));
}
ASSERT (remove (BASE "link") == 0);
+ /* Trailing slash on symlink to non-directory is an error. */
+ ASSERT (symlink (BASE "loop", BASE "loop") == 0);
+ errno = 0;
+ ASSERT (remove (BASE "loop/") == -1);
+ ASSERT (errno == ELOOP || errno == ENOTDIR);
+ ASSERT (remove (BASE "loop") == 0);
+ ASSERT (close (creat (BASE "file", 0600)) == 0);
+ ASSERT (symlink (BASE "file", BASE "link") == 0);
+ errno = 0;
+ ASSERT (remove (BASE "link/") == -1);
+ ASSERT (errno == ENOTDIR);
+ ASSERT (remove (BASE "link") == 0);
+ ASSERT (remove (BASE "file") == 0);
return 0;
}
diff --git a/tests/test-unlink.h b/tests/test-unlink.h
index 6b6384e50f..e65057de47 100644
--- a/tests/test-unlink.h
+++ b/tests/test-unlink.h
@@ -68,14 +68,17 @@ test_unlink_func (int (*func) (char const *name), bool print)
ASSERT (func (BASE "dir/file") == 0);
ASSERT (rmdir (BASE "dir") == 0);
if (print)
- fputs ("skipping test: symlinks not supported on this file system\n",
- stderr);
+ fputs ("skipping test: symlinks not supported on this file system\n",
+ stderr);
return 77;
}
if (cannot_unlink_dir ())
ASSERT (func (BASE "link/") == -1);
ASSERT (func (BASE "link") == 0);
ASSERT (symlink (BASE "dir/file", BASE "link") == 0);
+ errno = 0;
+ ASSERT (func (BASE "link/") == -1);
+ ASSERT (errno == ENOTDIR);
/* Order here proves unlink of a symlink does not follow through to
the file. */
ASSERT (func (BASE "link") == 0);