X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;ds=sidebyside;f=lib%2Frename-dest-slash.c;h=80660768a10736a7e48c912bd4ad4dd526d06ead;hb=8ec8f4b42e39d3aaf2dda06c38b8db00efcc69f5;hp=2c73f06d23b242f54f64ec089a4e7f455754e22a;hpb=23ba046d0ad85ab6e288a70902c0e0589169ff65;p=gnulib.git
diff --git a/lib/rename-dest-slash.c b/lib/rename-dest-slash.c
index 2c73f06d2..80660768a 100644
--- a/lib/rename-dest-slash.c
+++ b/lib/rename-dest-slash.c
@@ -8,10 +8,10 @@
Copyright (C) 2006 Free Software Foundation, Inc.
- This program is free software; you can redistribute it and/or modify
+ 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.
+ the Free Software Foundation; either version 3 of the License, 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
@@ -19,8 +19,7 @@
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. */
+ along with this program. If not, see . */
/* written by Jim Meyering */
@@ -31,22 +30,27 @@
#include
#include
+#include
#include
#include
-#include
#include "dirname.h"
#include "xalloc.h"
-static inline bool
-has_trailing_slash (char const *file, size_t len)
+static bool
+has_trailing_slash (char const *file)
{
- /* Don't count "/" as having a trailing slash. */
- if (len <= FILE_SYSTEM_PREFIX_LEN (file) + 1)
- return false;
+ /* Don't count "/", "//", etc., as having a trailing slash. */
+ bool has_non_slash = false;
+ bool ends_in_slash = false;
- char last = file[len - 1];
- return ISSLASH (last);
+ for (file += FILE_SYSTEM_PREFIX_LEN (file); *file; file++)
+ {
+ ends_in_slash = ISSLASH (*file);
+ has_non_slash |= ~ ends_in_slash;
+ }
+
+ return has_non_slash & ends_in_slash;
}
/* This is a rename wrapper for systems where the rename syscall
@@ -59,31 +63,25 @@ has_trailing_slash (char const *file, size_t len)
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;
-
- /* 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;
-
- {
- /* Fail now, unless SRC is a directory. */
- struct stat sb;
- if (lstat (src, &sb) != 0 || ! S_ISDIR (sb.st_mode))
- 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);
- }
+
+ if (ret_val != 0 && errno == ENOENT && has_trailing_slash (dst))
+ {
+ int rename_errno = ENOENT;
+
+ /* Fail now, unless SRC is a directory. */
+ struct stat sb;
+ if (lstat (src, &sb) == 0 && S_ISDIR (sb.st_mode))
+ {
+ char *dst_temp = xstrdup (dst);
+ strip_trailing_slashes (dst_temp);
+ ret_val = rename (src, dst_temp);
+ rename_errno = errno;
+ free (dst_temp);
+ }
+
+ errno = rename_errno;
+ }
return ret_val;
}