# HG changeset patch # User Jim Meyering # Date 1158328152 0 # Node ID 57043fbf87a2b166c586deef2503b5c6c6c08149 # Parent 7fab62b5331d14c40b0136af038a8ff4c88d8d68 [ChangeLog] * modules/rename-dest-slash: New module. * MODULES.html.sh (posix_compat): Add it here. [lib/ChangeLog] * rename-dest-slash.c: New file. [m4/ChangeLog] * rename-dest-slash.m4 (gl_FUNC_RENAME_TRAILING_DEST_SLASH): New file. diff --git a/ChangeLog b/ChangeLog --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2006-09-15 Jim Meyering + * modules/rename-dest-slash: New module. + * MODULES.html.sh (posix_compat): Add it here. + * modules/rename: Reflect vb_FUNC_RENAME -> gl_FUNC_RENAME change. 2009-09-13 Simon Josefsson diff --git a/MODULES.html.sh b/MODULES.html.sh --- a/MODULES.html.sh +++ b/MODULES.html.sh @@ -1836,6 +1836,7 @@ func_module d-ino func_module d-type func_module link-follow + func_module rename-dest-slash func_module rmdir-errno func_module unlink-busy func_module winsz-ioctl diff --git a/lib/ChangeLog b/lib/ChangeLog --- a/lib/ChangeLog +++ b/lib/ChangeLog @@ -1,3 +1,7 @@ +2006-09-15 Jim Meyering + + * rename-dest-slash.c: New file. + 2006-09-14 Bruno Haible * allocsa.c: Include unconditionally. diff --git a/lib/rename-dest-slash.c b/lib/rename-dest-slash.c new file mode 100644 --- /dev/null +++ b/lib/rename-dest-slash.c @@ -0,0 +1,89 @@ +/* A rename wrapper to make tools like mv -- that would normally rely + on the underlying rename syscall -- work more consistently. + On at least NetBSD 1.6, `rename ("dir", "B/")' fails when B doesn't + exist, whereas it succeeds on Linux-2.6.x and Solaris 10. This wrapper + provides an interface for systems like the former so that the tools + (namely mv) relying on the rename syscall have more consistent + semantics. + + Copyright (C) 2006 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +/* written by Jim Meyering */ + +#include +#undef rename + +#include +#include +#include + +#include +#include +#include + +#include "dirname.h" +#include "xalloc.h" + +static inline bool +has_trailing_slash (char const *file, size_t len) +{ + /* Don't count "/" as having a trailing slash. */ + if (len <= 1) + return false; + + char last = file[len - 1]; + return ISSLASH (last); +} + +/* This is a rename wrapper for systems where the rename syscall + works differently than desired when SRC is a directory and DST does + not exist but is specified with a trailing slash. On NetBSD 6.1, + rename fails in that case. On Linux and Solaris systems, it succeeds. + This wrapper makes it succeed on NetBSD by running the originally + requested rename, and if it fails due to the above scenario, calling + it again with DST's trailing slashes removed. */ +int +rpl_rename_dest_slash (char const *src, char const *dst) +{ + size_t d_len; + int ret_val = rename (src, dst); + if (ret_val == 0 || errno != ENOENT) + return ret_val; + + { + /* Fail now, unless SRC is a directory. */ + struct stat sb; + if (lstat (src, &sb) != 0 || ! S_ISDIR (sb.st_mode)) + return ret_val; + } + + /* Don't call rename again if there are no trailing slashes. */ + d_len = strlen (dst); + if ( ! has_trailing_slash (dst, d_len)) + return ret_val; + + { + char *dst_temp; + dst_temp = xmemdup (dst, d_len + 1); + strip_trailing_slashes (dst_temp); + + ret_val = rename (src, dst_temp); + free (dst_temp); + } + + return ret_val; +} diff --git a/m4/ChangeLog b/m4/ChangeLog --- a/m4/ChangeLog +++ b/m4/ChangeLog @@ -1,5 +1,7 @@ 2006-09-15 Jim Meyering + * rename-dest-slash.m4 (gl_FUNC_RENAME_TRAILING_DEST_SLASH): New file. + * rename.m4 (gl_FUNC_RENAME): Rename from vb_FUNC_RENAME. 2006-09-13 Simon Josefsson diff --git a/m4/rename-dest-slash.m4 b/m4/rename-dest-slash.m4 new file mode 100644 --- /dev/null +++ b/m4/rename-dest-slash.m4 @@ -0,0 +1,41 @@ +#serial 1 + +# Copyright (C) 2006 Free Software Foundation, Inc. +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# Derived from rename.m4. + +# A rename wrapper to make tools like mv -- that would normally +# rely on the underlying rename syscall -- work more consistently. + +AC_DEFUN([gl_FUNC_RENAME_TRAILING_DEST_SLASH], +[ + AC_CACHE_CHECK([whether rename is broken with respect to destintation slashes], + gl_cv_func_rename_trailing_dest_slash_bug, + [ + rm -rf conftest.d1 conftest.d2 + mkdir conftest.d1 || + AC_MSG_ERROR([cannot create temporary directory]) + AC_TRY_RUN([ +# include + int + main () + { + return (rename ("conftest.d1", "conftest.d2/") ? 1 : 0); + } + ], + gl_cv_func_rename_trailing_dest_slash_bug=no, + gl_cv_func_rename_trailing_dest_slash_bug=yes, + dnl When crosscompiling, assume rename is broken. + gl_cv_func_rename_trailing_dest_slash_bug=yes) + + rm -rf conftest.d1 conftest.d2 + ]) + if test $gl_cv_func_rename_trailing_dest_slash_bug = yes; then + AC_LIBOBJ(rename-dest-slash) + AC_DEFINE(rename, rpl_rename_dest_slash, + [Define to rpl_rename_dest_slash if the replacement function should be used.]) + fi +]) diff --git a/modules/rename-dest-slash b/modules/rename-dest-slash new file mode 100644 --- /dev/null +++ b/modules/rename-dest-slash @@ -0,0 +1,24 @@ +Description: +rename() function: change the name or location of a file. + +Files: +lib/rename-dest-slash.c +m4/rename-dest-slash.m4 + +Depends-on: +xalloc +dirname + +configure.ac: +gl_FUNC_RENAME_TRAILING_DEST_SLASH + +Makefile.am: + +Include: + + +License: +GPL + +Maintainer: +Jim Meyering