bug-coreutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: mv fails to move files


From: Jim Meyering
Subject: Re: mv fails to move files
Date: Fri, 28 Feb 2003 22:46:38 +0100

Iida Yosiaki <address@hidden> wrote:
> It seems for me that mv in coreutils 4.5.8 failes to move files
> in a certain condition.
>
> * How to reproduce the bug.
...

Thank you for the very nice bug report!

To reassure anyone who might be worrying about whether
this is serious, note that this happens only when hard-linked
files are moved (or copied with cp --preserve=link) onto existing
destination files without using a --backup option.

Your test actually exposed two problems:

  * how does mv (and cp --preserve=link) handle existing destination
    files that end up being the target of a link call?

  * how is the dev/ino<->filename mapping managed when a file with
    more than one hard link cannot be copied/moved

Here's how I've fixed the first one.
And with this fix, your example now works.

        * src/copy.c (copy_internal): When link fails because of an
        existing destination file, unlink that file and try again.
        Reported by Iida Yosiaki.

and of course, i've also added tests of cp and mv:

        * tests/mv/Makefile.am (TESTS): Add hard-2.
        * tests/mv/hard-2: New test for the above-fixed bug.
        Based on a test case from Iida Yosiaki.

Index: copy.c
===================================================================
RCS file: /fetish/cu/src/copy.c,v
retrieving revision 1.139
retrieving revision 1.140
diff -u -p -u -r1.139 -r1.140
--- copy.c      15 Dec 2002 20:54:29 -0000      1.139
+++ copy.c      28 Feb 2003 21:36:18 -0000      1.140
@@ -1,5 +1,5 @@
 /* copy.c -- core functions for copying files and directories
-   Copyright (C) 89, 90, 91, 1995-2002 Free Software Foundation.
+   Copyright (C) 89, 90, 91, 1995-2003 Free Software Foundation.
 
    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
@@ -1110,14 +1110,32 @@ copy_internal (const char *src_path, con
          goto un_backup;
        }
 
-      if (link (earlier_file, dst_path))
-       {
-         error (0, errno, _("cannot create hard link %s to %s"),
-                quote_n (0, dst_path), quote_n (1, earlier_file));
-         goto un_backup;
-       }
+      {
+       int link_failed;
 
-      return 0;
+       link_failed = link (earlier_file, dst_path);
+
+       /* If the link failed because of an existing destination,
+          remove that file and then call link again.  */
+       if (link_failed && errno == EEXIST)
+         {
+           if (unlink (dst_path))
+             {
+               error (0, errno, _("cannot remove %s"), quote (dst_path));
+               goto un_backup;
+             }
+           link_failed = link (earlier_file, dst_path);
+         }
+
+       if (link_failed)
+         {
+           error (0, errno, _("cannot create hard link %s to %s"),
+                  quote_n (0, dst_path), quote_n (1, earlier_file));
+           goto un_backup;
+         }
+
+       return 0;
+      }
     }
 
   if (x->move_mode)




reply via email to

[Prev in Thread] Current Thread [Next in Thread]