Commit 1fc2fce0 authored by Paul Eggert's avatar Paul Eggert

* lib/rename-dest-slash.c: Include stdbool.h but not string.h.

(has_trailing_slash): Omit size arg; all callers changed.
Omit 'inline', since it doesn't help performance and we'd
need to configure it.
Don't count //, ///, etc. as having a trailing slash.
As a side effect, this removes a C99ism reported by Matthew Woehlke.
(rpl_rename_dest_slash): On failure, use rename's errno rather
than (in some cases) an incorrect or junk errno.
Simplify code by removing need to compute length; this does
cause it to make two passes instead of one over the file name,
but it's worth it.
parent e70d209b
2006-10-11 Paul Eggert <eggert@cs.ucla.edu>
* lib/rename-dest-slash.c: Include stdbool.h but not string.h.
(has_trailing_slash): Omit size arg; all callers changed.
Omit 'inline', since it doesn't help performance and we'd
need to configure it.
Don't count //, ///, etc. as having a trailing slash.
As a side effect, this removes a C99ism reported by Matthew Woehlke.
(rpl_rename_dest_slash): On failure, use rename's errno rather
than (in some cases) an incorrect or junk errno.
Simplify code by removing need to compute length; this does
cause it to make two passes instead of one over the file name,
but it's worth it.
* m4/extensions.m4 (gl_USE_SYSTEM_EXTENSIONS): Undo previous
change, since Autoconf's version may no longer be appropriate now
that we are using CVS Autoconf's version. Add support for Tandem.
......
......@@ -31,22 +31,27 @@
#include <sys/stat.h>
#include <errno.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#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 +64,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;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment