diff options
author | sobomax <sobomax@FreeBSD.org> | 2001-04-26 17:15:57 +0000 |
---|---|---|
committer | sobomax <sobomax@FreeBSD.org> | 2001-04-26 17:15:57 +0000 |
commit | d7706ae588fda99a14527bcb330cfc62f83d69e2 (patch) | |
tree | 685d366d32d6daac21b4f56782098c25aadf60f4 /bin/ln | |
parent | 1b6f26ed7fe086681a9e3b13193823c0eeae7edd (diff) | |
download | FreeBSD-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.1 | 32 | ||||
-rw-r--r-- | bin/ln/ln.c | 35 |
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); } |