]> git.ipfire.org Git - thirdparty/coreutils.git/commitdiff
(do_link): Form destination file name (when DEST is a directory) before
authorJim Meyering <jim@meyering.net>
Mon, 1 Sep 1997 20:31:00 +0000 (20:31 +0000)
committerJim Meyering <jim@meyering.net>
Mon, 1 Sep 1997 20:31:00 +0000 (20:31 +0000)
checking whether SOURCE and DEST are the same file.

src/ln.c

index 492d4598a678fea83ff925989a42d2c49eaf818a..5e480a2a4e3eed44cdd5b796e2678c88958f6ac8 100644 (file)
--- a/src/ln.c
+++ b/src/ln.c
@@ -134,12 +134,16 @@ same_name (const char *source, const char *dest)
     error (1, 0, _("virtual memory exhausted"));
 
   if (stat (source_dirname, &source_dir_stats))
-    /* Shouldn't happen.  */
-    error (1, errno, "%s", source_dirname);
+    {
+      /* Shouldn't happen.  */
+      error (1, errno, "%s", source_dirname);
+    }
 
   if (stat (dest_dirname, &dest_dir_stats))
-    /* Shouldn't happen.  */
-    error (1, errno, "%s", dest_dirname);
+    {
+      /* Shouldn't happen.  */
+      error (1, errno, "%s", dest_dirname);
+    }
 
   free (source_dirname);
   free (dest_dirname);
@@ -181,13 +185,39 @@ do_link (const char *source, const char *dest)
     }
 
   lstat_status = lstat (dest, &dest_stats);
-
   if (lstat_status != 0 && errno != ENOENT)
     {
       error (0, errno, "%s", dest);
       return 1;
     }
 
+  /* If the destination is a directory or (it is a symlink to a directory
+     and the user has not specified --no-dereference), then form the
+     actual destination name by appending base_name (source) to the
+     specified destination directory.  */
+  if ((lstat_status == 0
+       && S_ISDIR (dest_stats.st_mode))
+#ifdef S_ISLNK
+      || (dereference_dest_dir_symlinks
+         && (S_ISLNK (dest_stats.st_mode)
+         && isdir (dest)))
+#endif
+     )
+    {
+      /* Target is a directory; build the full filename. */
+      char *new_dest;
+      PATH_BASENAME_CONCAT (new_dest, dest, source);
+      dest = new_dest;
+
+      /* Get stats for new DEST.  */
+      lstat_status = lstat (dest, &dest_stats);
+      if (lstat_status != 0 && errno != ENOENT)
+       {
+         error (0, errno, "%s", dest);
+         return 1;
+       }
+    }
+
   /* If --force (-f) has been specified without --backup, then before
      making a link ln must remove the destination file if it exists.
      (with --backup, it just renames any existing destination file)
@@ -214,28 +244,6 @@ do_link (const char *source, const char *dest)
       return 1;
     }
 
-  /* If the destination is a directory or (it is a symlink to a directory
-     and the user has not specified --no-dereference), then form the
-     actual destination name by appending base_name (source) to the
-     specified destination directory.  */
-  if ((lstat_status == 0
-       && S_ISDIR (dest_stats.st_mode))
-#ifdef S_ISLNK
-      || (dereference_dest_dir_symlinks
-         && (S_ISLNK (dest_stats.st_mode)
-         && isdir (dest)))
-#endif
-     )
-    {
-      /* Target is a directory; build the full filename. */
-      char *new_dest;
-      PATH_BASENAME_CONCAT (new_dest, dest, source);
-      dest = new_dest;
-      /* Set this to nonzero to force another call to lstat
-        with the new destination.  */
-      lstat_status = 1;
-    }
-
   if (lstat_status == 0 || lstat (dest, &dest_stats) == 0)
     {
       if (S_ISDIR (dest_stats.st_mode))