summaryrefslogtreecommitdiff
path: root/src/ln.c
diff options
context:
space:
mode:
authorJim Meyering <jim@meyering.net>2006-11-18 20:00:39 +0100
committerJim Meyering <jim@meyering.net>2006-11-18 20:00:39 +0100
commit0cafba44bbef7c5eb64979544a1ec95a389ec55f (patch)
tree7bfbb62a72231e651643c6545b5f00f697be1254 /src/ln.c
parent1a0333565f1a89d87b36e7a5c83bac9c145a9916 (diff)
downloadcoreutils-0cafba44bbef7c5eb64979544a1ec95a389ec55f.tar.xz
"ln --backup f f" produces a misleading diagnostic:
ln: creating hard link `f' => `f': No such file or directory * src/ln.c (do_link): Give a better diagnostic in this unusual case. (do_link): Rename local: s/lstat_ok/dest_lstat_ok/. * tests/ln/Makefile.am (TESTS): Add hard-backup. * tests/ln/hard-backup: New test for the above.
Diffstat (limited to 'src/ln.c')
-rw-r--r--src/ln.c18
1 files changed, 12 insertions, 6 deletions
diff --git a/src/ln.c b/src/ln.c
index 0aa5ac520..fae370807 100644
--- a/src/ln.c
+++ b/src/ln.c
@@ -133,7 +133,7 @@ do_link (const char *source, const char *dest)
struct stat source_stats;
struct stat dest_stats;
char *dest_backup = NULL;
- bool lstat_ok = false;
+ bool dest_lstat_ok = false;
bool source_is_dir = false;
bool ok;
@@ -171,8 +171,8 @@ do_link (const char *source, const char *dest)
if (remove_existing_files || interactive || backup_type != no_backups)
{
- lstat_ok = (lstat (dest, &dest_stats) == 0);
- if (!lstat_ok && errno != ENOENT)
+ dest_lstat_ok = (lstat (dest, &dest_stats) == 0);
+ if (!dest_lstat_ok && errno != ENOENT)
{
error (0, errno, _("accessing %s"), quote (dest));
return false;
@@ -184,8 +184,14 @@ do_link (const char *source, const char *dest)
(with --backup, it just renames any existing destination file)
But if the source and destination are the same, don't remove
anything and fail right here. */
- if (remove_existing_files
- && lstat_ok
+ if ((remove_existing_files
+ /* Ensure that "ln --backup f f" fails here, with the
+ "... same file" diagnostic, below. Otherwise, subsequent
+ code would give a misleading "file not found" diagnostic.
+ This case is different than the others handled here, since
+ the command in question doesn't use --force. */
+ || (!symbolic_link && backup_type != no_backups))
+ && dest_lstat_ok
/* Allow `ln -sf --backup k k' to succeed in creating the
self-referential symlink, but don't allow the hard-linking
equivalent: `ln -f k k' (with or without --backup) to get
@@ -205,7 +211,7 @@ do_link (const char *source, const char *dest)
return false;
}
- if (lstat_ok)
+ if (dest_lstat_ok)
{
if (S_ISDIR (dest_stats.st_mode))
{