]> git.ipfire.org Git - thirdparty/coreutils.git/commitdiff
(copy_internal): cp -RL no longer fails when encountering
authorJim Meyering <jim@meyering.net>
Sat, 4 Feb 2006 10:49:21 +0000 (10:49 +0000)
committerJim Meyering <jim@meyering.net>
Sat, 4 Feb 2006 10:49:21 +0000 (10:49 +0000)
the same directory more than once in the hierarchy beneath a single
command-line argument.  That is legitimate, e.g. when there are
two or more symbolic links, each pointing to some directory that
would not otherwise be copied.  Reported by Christophe LYON.

src/copy.c

index ba8c4e1897c9cfc4d7f89fddf160bbef2b9e3ae8..8a9f7d101e46815ca74effb12dee6d5c41590af7 100644 (file)
@@ -1302,40 +1302,49 @@ copy_internal (char const *src_name, char const *dst_name,
                     quote_n (0, top_level_src_name),
                     quote_n (1, top_level_dst_name));
              *copy_into_self = true;
+             goto un_backup;
+           }
+         else if (x->dereference == DEREF_ALWAYS)
+           {
+             /* This happens when e.g., encountering a directory for the
+                second or subsequent time via symlinks when cp is invoked
+                with -R and -L.  E.g.,
+                rm -rf a b c d; mkdir a b c d; ln -s ../c a; ln -s ../c b;
+                cp -RL a b d
+             */
            }
          else
            {
              error (0, 0, _("will not create hard link %s to directory %s"),
                     quote_n (0, dst_name), quote_n (1, earlier_file));
+             goto un_backup;
            }
-
-         goto un_backup;
        }
+      else
+       {
+         bool link_failed = (link (earlier_file, dst_name) != 0);
 
-      {
-       bool link_failed = (link (earlier_file, dst_name) != 0);
-
-       /* 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_name) != 0)
-             {
-               error (0, errno, _("cannot remove %s"), quote (dst_name));
-               goto un_backup;
-             }
-           link_failed = (link (earlier_file, dst_name) != 0);
-         }
-
-       if (link_failed)
-         {
-           error (0, errno, _("cannot create hard link %s to %s"),
-                  quote_n (0, dst_name), quote_n (1, earlier_file));
-           goto un_backup;
-         }
+         /* 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_name) != 0)
+               {
+                 error (0, errno, _("cannot remove %s"), quote (dst_name));
+                 goto un_backup;
+               }
+             link_failed = (link (earlier_file, dst_name) != 0);
+           }
 
-       return true;
-      }
+         if (link_failed)
+           {
+             error (0, errno, _("cannot create hard link %s to %s"),
+                    quote_n (0, dst_name), quote_n (1, earlier_file));
+             goto un_backup;
+           }
+
+         return true;
+       }
     }
 
   if (x->move_mode)