bug-coreutils
[Top][All Lists]
Advanced

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

Re: posix & links


From: Jim Meyering
Subject: Re: posix & links
Date: Sat, 03 Jun 2006 11:12:04 +0200

Michael Stone <address@hidden> wrote:
> Have you seen this bug report?
>
> http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=329451

Yes.
I've just dealt with it on the upstream trunk:

2006-06-03  Jim Meyering  <address@hidden>

        Make `cp --link --no-dereference' work also on systems where the
        link system call cannot create a hard link to a symbolic link.
        * src/copy.c (copy_internal) [LINK_FOLLOWS_SYMLINKS]: Don't use
        the link syscall on a symlink when it would do the wrong thing.
        Based on the patch by Aurelien Jarno: <http://bugs.debian.org/329451>
        * tests/cp/link-no-deref: New file/test for the above.
        * tests/cp/Makefile.am (TESTS): Add link-no-deref.
        * NEWS: Mention the change (doesn't affect Linux).

Index: src/copy.c
===================================================================
RCS file: /fetish/cu/src/copy.c,v
retrieving revision 1.199
retrieving revision 1.200
diff -u -p -u -r1.199 -r1.200
--- src/copy.c  11 May 2006 08:55:04 -0000      1.199
+++ src/copy.c  3 Jun 2006 09:04:22 -0000       1.200
@@ -1594,7 +1594,22 @@ copy_internal (char const *src_name, cha
        }
     }
 #endif
-  else if (x->hard_link)
+
+  else if (x->hard_link
+#ifdef LINK_FOLLOWS_SYMLINKS
+  /* A POSIX-conforming link syscall dereferences a symlink, yet cp,
+     invoked with `--link --no-dereference', should not.  Thus, with
+     a POSIX-conforming link system call, we can't use link() here,
+     since that would create a hard link to the referent (effectively
+     dereferencing the symlink), rather than to the symlink itself.
+     We can approximate the desired behavior by skipping this hard-link
+     creating block and instead copying the symlink, via the `S_ISLNK'-
+     copying code below.
+     When link operates on the symlinks themselves, we use this block
+     and just call link().  */
+          && !(S_ISLNK (src_mode) && x->dereference == DEREF_NEVER)
+#endif
+          )
     {
       preserve_metadata = false;
       if (link (src_name, dst_name))




reply via email to

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