rename-dest-slash: fix NetBSD bug
authorEric Blake <ebb9@byu.net>
Thu, 1 Oct 2009 00:57:02 +0000 (18:57 -0600)
committerEric Blake <ebb9@byu.net>
Fri, 2 Oct 2009 11:58:38 +0000 (05:58 -0600)
rename("hard1","hard2") mistakenly removed the hard link "hard1".

* lib/rename-dest-slash.c (rpl_rename_dest_slash): Detect hard
links.
* modules/rename-dest-slash (Depends-on): Add same-inode.

Signed-off-by: Eric Blake <ebb9@byu.net>
ChangeLog
lib/rename-dest-slash.c
modules/rename-dest-slash

index f13340f..ba1cea5 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
 2009-10-02  Eric Blake  <ebb9@byu.net>
 
+       rename-dest-slash: fix NetBSD bug
+       * lib/rename-dest-slash.c (rpl_rename_dest_slash): Detect hard
+       links.
+       * modules/rename-dest-slash (Depends-on): Add same-inode.
+
        rename-tests: new test, exposes several platform bugs
        * modules/rename-tests: New file.
        * tests/test-rename.h: Likewise.
index 8066076..2014fb1 100644 (file)
@@ -6,7 +6,7 @@
    (namely mv) relying on the rename syscall have more consistent
    semantics.
 
-   Copyright (C) 2006 Free Software Foundation, Inc.
+   Copyright (C) 2006, 2009 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
@@ -35,6 +35,7 @@
 #include <stdlib.h>
 
 #include "dirname.h"
+#include "same-inode.h"
 #include "xalloc.h"
 
 static bool
@@ -63,14 +64,22 @@ has_trailing_slash (char const *file)
 int
 rpl_rename_dest_slash (char const *src, char const *dst)
 {
-  int ret_val = rename (src, dst);
+  struct stat sb;
+  struct stat db;
+  int ret_val;
+
+  if (lstat (src, &sb))
+    return -1;
+  if (lstat (dst, &db) == 0 && SAME_INODE (sb, db))
+    return 0;
+
+  ret_val = rename (src, dst);
 
   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);
index d45fe5b..c0bc98d 100644 (file)
@@ -6,8 +6,9 @@ lib/rename-dest-slash.c
 m4/rename-dest-slash.m4
 
 Depends-on:
-xalloc
 dirname
+same-inode
+xalloc
 
 configure.ac:
 gl_FUNC_RENAME_TRAILING_DEST_SLASH