mirror of
https://github.com/freebsd/freebsd-src.git
synced 2024-12-03 14:48:57 +00:00
Bring in -h' compatability option and its alias
-n' to match NetBSD and GNU
semantics. style(9) Reviewed by: Obtained from: NetBSD
This commit is contained in:
parent
05f91f8d49
commit
c9e7c66776
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=76039
32
bin/ln/ln.1
32
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 STANDARDS
|
||||
The
|
||||
.Nm
|
||||
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 .
|
||||
The simplified
|
||||
.Nm link
|
||||
command conforms to
|
||||
.St -susv2 .
|
||||
|
35
bin/ln/ln.c
35
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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user