From: Jim Meyering Date: Sun, 27 Jun 2004 09:41:23 +0000 (+0000) Subject: Fix a bug: formerly, if d/x was a directory and x a file, "ln x X-Git-Tag: v5.3.0~1245 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=54cdcb1a1a2fe3b9b16c48427c96aa0b579d58c2;p=thirdparty%2Fcoreutils.git Fix a bug: formerly, if d/x was a directory and x a file, "ln x d/" incorrectly created a link d/x/x. It also saves some system calls. (main): Don't append basename to dest if this results in an existing directory name. --- diff --git a/src/ln.c b/src/ln.c index 9b2d730380..7801b2c275 100644 --- a/src/ln.c +++ b/src/ln.c @@ -550,25 +550,31 @@ main (int argc, char **argv) else { struct stat source_stats; - char *new_dest; char const *source = file[0]; char *dest = file[1]; size_t destlen = strlen (dest); + char *new_dest = dest; /* When the destination is specified with a trailing slash and the source exists but is not a directory, convert the user's command - `ln source dest/' to `ln source dest/basename(source)'. */ + `ln source dest/' to `ln source dest/basename(source)'. + However, skip this step if dest/basename(source) is a directory. */ if (destlen != 0 && dest[destlen - 1] == '/' && lstat (source, &source_stats) == 0 && !S_ISDIR (source_stats.st_mode)) { - PATH_BASENAME_CONCAT (new_dest, dest, source); - } - else - { - new_dest = dest; + struct stat dest_stats; + char *dest_plus_source_basename; + + PATH_BASENAME_CONCAT (dest_plus_source_basename, dest, source); + + if (! ((((dereference_dest_dir_symlinks ? stat : lstat) + (dest_plus_source_basename, &dest_stats)) + == 0) + && S_ISDIR (dest_stats.st_mode))) + new_dest = dest_plus_source_basename; } errors = do_link (source, new_dest);