summaryrefslogtreecommitdiffstats
path: root/bin/ln
diff options
context:
space:
mode:
authorsobomax <sobomax@FreeBSD.org>2001-04-26 17:15:57 +0000
committersobomax <sobomax@FreeBSD.org>2001-04-26 17:15:57 +0000
commitd7706ae588fda99a14527bcb330cfc62f83d69e2 (patch)
tree685d366d32d6daac21b4f56782098c25aadf60f4 /bin/ln
parent1b6f26ed7fe086681a9e3b13193823c0eeae7edd (diff)
downloadFreeBSD-src-d7706ae588fda99a14527bcb330cfc62f83d69e2.zip
FreeBSD-src-d7706ae588fda99a14527bcb330cfc62f83d69e2.tar.gz
Bring in `-h' compatability option and its alias `-n' to match NetBSD and GNU
semantics. style(9) Reviewed by: Obtained from: NetBSD
Diffstat (limited to 'bin/ln')
-rw-r--r--bin/ln/ln.132
-rw-r--r--bin/ln/ln.c35
2 files changed, 53 insertions, 14 deletions
diff --git a/bin/ln/ln.1 b/bin/ln/ln.1
index 6eb4f60..ec9d61e 100644
--- a/bin/ln/ln.1
+++ b/bin/ln/ln.1
@@ -44,11 +44,11 @@
.Nd make links
.Sh SYNOPSIS
.Nm
-.Op Fl fisv
+.Op Fl fhinsv
.Ar source_file
.Op target_file
.Nm
-.Op Fl fisv
+.Op Fl fhinsv
.Ar source_file ...
.Op target_dir
.Nm link
@@ -79,6 +79,14 @@ then unlink it so that the link may occur.
option overrides any previous
.Fl i
options.)
+.It Fl h
+If the
+.Ar target_file
+or
+.Ar target_dir
+is a symbolic link, do not follow it. This is most useful with the
+.Fl f
+option, to replace a symlink which may point to a directory.
.It Fl i
Cause
.Nm
@@ -94,6 +102,12 @@ Otherwise, do not attempt the link.
option overrides any previous
.Fl f
options.)
+.It Fl n
+Same as
+.Fl h ,
+for compatibility with other
+.Nm
+implementations.
.It Fl s
Create a symbolic link.
.It Fl v
@@ -168,12 +182,18 @@ The
and
.Fl v
options are non-standard and their use in scripts is not recommended.
-.Sh HISTORY
-An
+.Sh STANDARDS
+The
.Nm
-command appeared in
-.At v1 .
+utility conforms to
+.St -p1003.2-92 .
+.Pp
The simplified
.Nm link
command conforms to
.St -susv2 .
+.Sh HISTORY
+An
+.Nm
+command appeared in
+.At v1 .
diff --git a/bin/ln/ln.c b/bin/ln/ln.c
index 27c6a82..83fe651 100644
--- a/bin/ln/ln.c
+++ b/bin/ln/ln.c
@@ -56,6 +56,7 @@ static const char rcsid[] =
#include <unistd.h>
int fflag; /* Unlink existing files. */
+int hflag; /* Check new name for symlink first. */
int iflag; /* Interactive mode. */
int sflag; /* Symbolic, not hard, link. */
int vflag; /* Verbose output. */
@@ -64,6 +65,7 @@ int (*linkf) __P((const char *, const char *));
char linkch;
int linkit __P((char *, char *, int));
+int main __P((int, char *[]));
void usage __P((void));
int
@@ -92,12 +94,16 @@ main(argc, argv)
usage();
}
- while ((ch = getopt(argc, argv, "fisv")) != -1)
+ while ((ch = getopt(argc, argv, "fhinsv")) != -1)
switch (ch) {
case 'f':
fflag = 1;
iflag = 0;
break;
+ case 'h':
+ case 'n':
+ hflag = 1;
+ break;
case 'i':
iflag = 1;
fflag = 0;
@@ -122,6 +128,7 @@ main(argc, argv)
switch(argc) {
case 0:
usage();
+ /* NOTREACHED */
case 1: /* ln target */
exit(linkit(argv[0], ".", 1));
case 2: /* ln target source */
@@ -129,6 +136,14 @@ main(argc, argv)
}
/* ln target1 target2 directory */
sourcedir = argv[argc - 1];
+ if (hflag && lstat(sourcedir, &sb) == 0 && S_ISLNK(sb.st_mode)) {
+ /*
+ * We were asked not to follow symlinks, but found one at
+ * the target--simulate "not a directory" error
+ */
+ errno = ENOTDIR;
+ err(1, "%s", sourcedir);
+ }
if (stat(sourcedir, &sb))
err(1, "%s", sourcedir);
if (!S_ISDIR(sb.st_mode))
@@ -161,18 +176,22 @@ linkit(target, source, isdir)
}
}
- /* If the source is a directory, append the target's name. */
- if (isdir || ((exists = !stat(source, &sb)) && S_ISDIR(sb.st_mode))) {
+ /*
+ * If the source is a directory (and not a symlink if hflag),
+ * append the target's name.
+ */
+ if (isdir ||
+ (lstat(source, &sb) == 0 && S_ISDIR(sb.st_mode)) ||
+ (!hflag && stat(source, &sb) == 0 && S_ISDIR(sb.st_mode))) {
if ((p = strrchr(target, '/')) == NULL)
p = target;
else
++p;
(void)snprintf(path, sizeof(path), "%s/%s", source, p);
source = path;
- exists = !lstat(source, &sb);
- } else
- exists = !lstat(source, &sb);
+ }
+ exists = !lstat(source, &sb);
/*
* If the file exists, then unlink it forcibly if -f was specified
* and interactively if -i was specified.
@@ -214,8 +233,8 @@ void
usage()
{
(void)fprintf(stderr, "%s\n%s\n%s\n",
- "usage: ln [-fisv] file1 file2",
- " ln [-fisv] file ... directory",
+ "usage: ln [-fhinsv] file1 file2",
+ " ln [-fhinsv] file ... directory",
" link file1 file2");
exit(1);
}
OpenPOWER on IntegriCloud