PR/22799: Hiramatsu Yoshifumi: Add -i option to /bin/ln

Slightly modified patch applied, thanks!
This commit is contained in:
elad 2006-10-07 10:05:25 +00:00
parent ed23b39f46
commit cf245f1ee7
2 changed files with 58 additions and 11 deletions

View File

@ -1,4 +1,4 @@
.\" $NetBSD: ln.1,v 1.20 2003/08/07 09:05:14 agc Exp $
.\" $NetBSD: ln.1,v 1.21 2006/10/07 10:05:25 elad Exp $
.\"
.\" Copyright (c) 1980, 1990, 1993
.\" The Regents of the University of California. All rights reserved.
@ -32,7 +32,7 @@
.\"
.\" @(#)ln.1 8.2 (Berkeley) 12/30/93
.\"
.Dd December 26, 2002
.Dd October 7, 2006
.Dt LN 1
.Os
.Sh NAME
@ -40,11 +40,11 @@
.Nd make links
.Sh SYNOPSIS
.Nm
.Op Fl fhnsv
.Op Fl fhinsv
.Ar source_file
.Op Ar target_file
.Nm
.Op Fl fhnsv
.Op Fl fhinsv
.Ar source_file ... target_dir
.Sh DESCRIPTION
The
@ -73,6 +73,21 @@ or
.Ar target_dir
is a symbolic link, do not follow it.
This is most useful with the
.Fl i
Cause
.Nm
to write a prompt to standard error if the target file exists.
If the response from the standard input begins with the character
.Sq Li y
or
.Sq Li Y ,
then unlink the target file so that the link may occur.
Otherwise, do not attempt the link.
(The
.Fl i
option override any previous
.Fl f
options.)
.Fl f
option, to replace a symlink which may point to a directory.
.It Fl n

View File

@ -1,4 +1,4 @@
/* $NetBSD: ln.c,v 1.30 2005/06/26 19:10:49 christos Exp $ */
/* $NetBSD: ln.c,v 1.31 2006/10/07 10:05:25 elad Exp $ */
/*
* Copyright (c) 1987, 1993, 1994
@ -39,7 +39,7 @@ __COPYRIGHT("@(#) Copyright (c) 1987, 1993, 1994\n\
#if 0
static char sccsid[] = "@(#)ln.c 8.2 (Berkeley) 3/31/94";
#else
__RCSID("$NetBSD: ln.c,v 1.30 2005/06/26 19:10:49 christos Exp $");
__RCSID("$NetBSD: ln.c,v 1.31 2006/10/07 10:05:25 elad Exp $");
#endif
#endif /* not lint */
@ -55,6 +55,7 @@ __RCSID("$NetBSD: ln.c,v 1.30 2005/06/26 19:10:49 christos Exp $");
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 */
@ -74,15 +75,20 @@ main(int argc, char *argv[])
char *sourcedir;
setprogname(argv[0]);
while ((ch = getopt(argc, argv, "fhnsv")) != -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;
break;
case 's':
sflag = 1;
break;
@ -147,6 +153,7 @@ linkit(const char *target, const char *source, int isdir)
struct stat sb;
const char *p;
char path[MAXPATHLEN];
int ch, exists, first;
if (!sflag) {
/* If target doesn't exist, quit now. */
@ -169,12 +176,37 @@ linkit(const char *target, const char *source, int isdir)
source = path;
}
exists = !lstat(source, &sb);
/*
* If the file exists, and -f was specified, unlink it.
* Attempt the link.
* If the file exists, then unlink it forcibly if -f was specified
* and interactively if -i was specified.
*/
if ((fflag && unlink(source) < 0 && errno != ENOENT) ||
(*linkf)(target, source)) {
if (fflag && exists) {
if (unlink(source)) {
warn("%s", source);
return (1);
}
} else if (iflag && exists) {
fflush(stdout);
(void)fprintf(stderr, "replace %s? ", source);
first = ch = getchar();
while (ch != '\n' && ch != EOF)
ch = getchar();
if (first != 'y' && first != 'Y') {
(void)fprintf(stderr, "not replaced\n");
return (1);
}
if (unlink(source)) {
warn("%s", source);
return (1);
}
}
/* Attempt the link. */
if ((*linkf)(target, source)) {
warn("%s", source);
return (1);
}