GNU bug report logs - #6960
mv refuses to move a symlink over a hard link to the same file

Previous Next

Package: coreutils;

Reported by: Matt McCutchen <matt <at> mattmccutchen.net>

Date: Tue, 31 Aug 2010 21:27:01 UTC

Severity: normal

Done: Jim Meyering <jim <at> meyering.net>

Bug is archived. No further changes may be made.

Full log


View this message in rfc822 format

From: Pádraig Brady <P <at> draigBrady.com>
To: Jim Meyering <jim <at> meyering.net>
Cc: Paul Eggert <eggert <at> cs.ucla.edu>, 6960 <at> debbugs.gnu.org, Anders Kaseorg <andersk <at> MIT.EDU>
Subject: bug#6960: mv refuses to move a symlink over a hard link to the same file
Date: Sun, 29 Jan 2012 22:05:44 +0000
On 01/29/2012 09:33 PM, Jim Meyering wrote:

> diff --git a/src/copy.c b/src/copy.c
> index 51f51be..af79ed3 100644
> --- a/src/copy.c
> +++ b/src/copy.c
> @@ -34,6 +34,7 @@
>  #include "acl.h"
>  #include "backupfile.h"
>  #include "buffer-lcm.h"
> +#include "canonicalize.h"
>  #include "copy.h"
>  #include "cp-hash.h"
>  #include "extent-scan.h"
> @@ -1349,6 +1350,38 @@ same_file_ok (char const *src_name, struct stat const *src_sb,
>          }
>      }
> 
> +  /* At this point, it is normally an error (data loss) to move a symlink
> +     onto its referent, but in at least one narrow case, it is not:
> +     In move mode, when
> +     src is a symlink,
> +     dest is not a symlink,
> +     dest has a link count of 2 or more and
> +     dest and the referent of src are not the same entry,
> +     then it's ok, since while we'll lose one of those hard links,
> +     src will still point to a remaining link.
> +
> +     Given this,
> +       $ touch f && ln f l && ln -s f s
> +       $ ls -og f l s
> +       -rw-------. 2  0 Jan  4 22:46 f
> +       -rw-------. 2  0 Jan  4 22:46 l
> +       lrwxrwxrwx. 1  1 Jan  4 22:46 s -> f
> +     this must fail: mv s f
> +     this must succeed: mv s l */
> +  if (x->move_mode
> +      && S_ISLNK (src_sb->st_mode)
> +      && ! S_ISLNK (dst_sb->st_mode)
> +      && 1 < dst_sb_link->st_nlink)
> +    {
> +      char *abs_src = canonicalize_file_name (src_name);
> +      if (abs_src)
> +        {
> +          bool result = ! same_name (abs_src, dst_name);
> +          free (abs_src);
> +          return result;
> +        }
> +    }

Well the logic follows the description at least.
I was going to say the nlink test was redundant,
but it's a bit clearer with that left, and also
it's a performance improvement in the nlink=1 case.

cheers,
Pádraig.




This bug report was last modified 13 years and 179 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.