Mercurial > hg > octave-lojdl > gnulib-hg
changeset 12260:18ce29e54b9f
rename: detect FreeBSD bug
rename("link-to-file/","new") mistakenly succeeded.
* m4/rename.m4 (gl_FUNC_RENAME): Also detect FreeBSD bug with
slash on symlink.
* modules/renameat-tests (Depends-on): Add filenamecat.
* tests/test-rename.h (test_rename): Allow one more errno.
* tests/test-renameat.c (main): Likewise.
* doc/posix-functions/rename.texi (rename): Document the bug.
Signed-off-by: Eric Blake <ebb9@byu.net>
author | Eric Blake <ebb9@byu.net> |
---|---|
date | Sun, 08 Nov 2009 18:11:50 -0700 |
parents | 80f02cc1739e |
children | e96aac709428 |
files | ChangeLog doc/posix-functions/rename.texi m4/rename.m4 modules/renameat-tests tests/test-rename.h tests/test-renameat.c |
diffstat | 6 files changed, 48 insertions(+), 12 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,13 @@ 2009-11-09 Eric Blake <ebb9@byu.net> + rename: detect FreeBSD bug + * m4/rename.m4 (gl_FUNC_RENAME): Also detect FreeBSD bug with + slash on symlink. + * modules/renameat-tests (Depends-on): Add filenamecat. + * tests/test-rename.h (test_rename): Allow one more errno. + * tests/test-renameat.c (main): Likewise. + * doc/posix-functions/rename.texi (rename): Document the bug. + open: detect FreeBSD bug * m4/open.m4 (gl_FUNC_OPEN): Also detect FreeBSD bug with slash on symlink.
--- a/doc/posix-functions/rename.texi +++ b/doc/posix-functions/rename.texi @@ -13,10 +13,15 @@ destination directory, as in @code{rename("dir","new/")}: NetBSD 1.6. @item -This function does not reject trailing slashes on non-directories on -some platforms, as in @code{rename("file","new/")}: +This function does not reject trailing slashes on the destination for +non-directories on some platforms, as in @code{rename("file","new/")}: Solaris 10, Cygwin 1.5.x, mingw. @item +This function does not reject trailing slashes on symlinks to +non-directories on some platforms, as in +@code{rename("link-to-file/","f")}: +FreeBSD 7.2. +@item This function ignores trailing slashes on symlinks on some platforms, such that @code{rename("link/","new")} corrupts @file{link}: Solaris 9.
--- a/m4/rename.m4 +++ b/m4/rename.m4 @@ -1,4 +1,4 @@ -# serial 20 +# serial 21 # Copyright (C) 2001, 2003, 2005, 2006, 2009 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation @@ -17,28 +17,38 @@ [ AC_REQUIRE([AC_CANONICAL_HOST]) AC_REQUIRE([gl_STDIO_H_DEFAULTS]) + AC_CHECK_FUNCS_ONCE([lstat]) dnl Solaris 10 mistakenly allows rename("file","name/"). dnl NetBSD 1.6 mistakenly forbids rename("dir","name/"). + dnl FreeBSD 7.2 mistakenly allows rename("file","link-to-file/"). dnl The Solaris bug can be worked around without stripping dnl trailing slash, while the NetBSD bug requires stripping; dnl the two conditions can be distinguished by whether hard dnl links are also broken. AC_CACHE_CHECK([whether rename honors trailing slash on destination], [gl_cv_func_rename_slash_dst_works], - [rm -rf conftest.f conftest.f1 conftest.d1 conftest.d2 + [rm -rf conftest.f conftest.f1 conftest.d1 conftest.d2 conftest.lnk touch conftest.f && mkdir conftest.d1 || AC_MSG_ERROR([cannot create temporary files]) + # Assume that if we have lstat, we can also check symlinks. + if test $ac_cv_func_lstat = yes; then + ln -s conftest.f conftest.lnk + fi AC_RUN_IFELSE([AC_LANG_PROGRAM([[ # include <stdio.h> # include <stdlib.h> ]], [if (rename ("conftest.f", "conftest.f1/") == 0) return 1; - if (rename ("conftest.d1", "conftest.d2/") != 0) return 2;])], + if (rename ("conftest.d1", "conftest.d2/") != 0) return 2; +#if HAVE_LSTAT + if (rename ("conftest.f", "conftest.lnk/") == 0) return 3; +#endif + ])], [gl_cv_func_rename_slash_dst_works=yes], [gl_cv_func_rename_slash_dst_works=no], dnl When crosscompiling, assume rename is broken. [gl_cv_func_rename_slash_dst_works="guessing no"]) - rm -rf conftest.f conftest.f1 conftest.d1 conftest.d2 + rm -rf conftest.f conftest.f1 conftest.d1 conftest.d2 conftest.lnk ]) if test "x$gl_cv_func_rename_slash_dst_works" != xyes; then AC_LIBOBJ([rename]) @@ -50,23 +60,32 @@ dnl SunOS 4.1.1_U1 mistakenly forbids rename("dir/","name"). dnl Solaris 9 mistakenly allows rename("file/","name"). + dnl FreeBSD 7.2 mistakenly allows rename("link-to-file/","name"). dnl These bugs require stripping trailing slash to avoid corrupting dnl symlinks with a trailing slash. AC_CACHE_CHECK([whether rename honors trailing slash on source], [gl_cv_func_rename_slash_src_works], - [rm -rf conftest.f conftest.d1 conftest.d2 + [rm -rf conftest.f conftest.d1 conftest.d2 conftest.lnk touch conftest.f && mkdir conftest.d1 || AC_MSG_ERROR([cannot create temporary files]) + # Assume that if we have lstat, we can also check symlinks. + if test $ac_cv_func_lstat = yes; then + ln -s conftest.f conftest.lnk + fi AC_RUN_IFELSE([AC_LANG_PROGRAM([[ # include <stdio.h> # include <stdlib.h> ]], [if (rename ("conftest.f/", "conftest.d2") == 0) return 1; - if (rename ("conftest.d1/", "conftest.d2") != 0) return 2;])], + if (rename ("conftest.d1/", "conftest.d2") != 0) return 2; +#if HAVE_LSTAT + if (rename ("conftest.lnk/", "conftest.f") == 0) return 3; +#endif + ])], [gl_cv_func_rename_slash_src_works=yes], [gl_cv_func_rename_slash_src_works=no], dnl When crosscompiling, assume rename is broken. [gl_cv_func_rename_slash_src_works="guessing no"]) - rm -rf conftest.f conftest.d1 conftest.d2 + rm -rf conftest.f conftest.d1 conftest.d2 conftest.lnk ]) if test "x$gl_cv_func_rename_slash_src_works" != xyes; then AC_LIBOBJ([rename])
--- a/modules/renameat-tests +++ b/modules/renameat-tests @@ -3,6 +3,7 @@ tests/test-renameat.c Depends-on: +filenamecat progname xgetcwd
--- a/tests/test-rename.h +++ b/tests/test-rename.h @@ -138,7 +138,8 @@ ASSERT (mkdir (BASE "dir", 0700) == 0); errno = 0; ASSERT (func (BASE "dir2", BASE "dir/.") == -1); - ASSERT (errno == EINVAL || errno == EBUSY || errno == EISDIR); + ASSERT (errno == EINVAL || errno == EBUSY || errno == EISDIR + || errno == ENOTEMPTY); errno = 0; ASSERT (func (BASE "dir2/.", BASE "dir") == -1); ASSERT (errno == EINVAL || errno == EBUSY); @@ -149,7 +150,8 @@ ASSERT (mkdir (BASE "dir", 0700) == 0); errno = 0; ASSERT (func (BASE "dir2", BASE "dir/.//") == -1); - ASSERT (errno == EINVAL || errno == EBUSY || errno == EISDIR); + ASSERT (errno == EINVAL || errno == EBUSY || errno == EISDIR + || errno == ENOTEMPTY); errno = 0; ASSERT (func (BASE "dir2/.//", BASE "dir") == -1); ASSERT (errno == EINVAL || errno == EBUSY);
--- a/tests/test-renameat.c +++ b/tests/test-renameat.c @@ -134,7 +134,8 @@ ASSERT (unlink (BASE "sub2/file") == 0); errno = 0; ASSERT (renameat (dfd, BASE "sub2", dfd, BASE "sub1/.") == -1); - ASSERT (errno == EINVAL || errno == EISDIR || errno == EBUSY); + ASSERT (errno == EINVAL || errno == EISDIR || errno == EBUSY + || errno == ENOTEMPTY); errno = 0; ASSERT (renameat (dfd, BASE "sub2/.", dfd, BASE "sub1") == -1); ASSERT (errno == EINVAL || errno == EBUSY);