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:
Maxim Sobolev 2001-04-26 17:15:57 +00:00
parent 05f91f8d49
commit c9e7c66776
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=76039
2 changed files with 53 additions and 14 deletions

View file

@ -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 .

View file

@ -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);
}