From 54cdcb1a1a2fe3b9b16c48427c96aa0b579d58c2 Mon Sep 17 00:00:00 2001 From: Jim Meyering Date: Sun, 27 Jun 2004 09:41:23 +0000 Subject: 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. --- src/ln.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) (limited to 'src/ln.c') diff --git a/src/ln.c b/src/ln.c index 9b2d73038..7801b2c27 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); -- cgit v1.2.3-54-g00ecf