bin/92149 : [patch] ln(1): ln -f -s does not remove existing
directory
Eugene Grosbein
eugen at grosbein.pp.ru
Mon Feb 13 10:30:12 PST 2006
The following reply was made to PR bin/92149; it has been noted by GNATS.
From: Eugene Grosbein <eugen at grosbein.pp.ru>
To: bug-followup at freebsd.org
Cc: Gleb Smirnoff <glebius at freebsd.org>
Subject: Re: bin/92149 : [patch] ln(1): ln -f -s does not remove existing directory
Date: Tue, 14 Feb 2006 01:23:32 +0700
E>> Then I'd like to introduce new command line option enabling desired
E>> behavour. Should I correct the patch?
> Yes, I think this will be acceptable.
Here it comes. It introduces new option -F that implies -f
and removes empty target directory when dealing with symlinks.
Index: ln.1
===================================================================
RCS file: /home/ncvs/src/bin/ln/ln.1,v
retrieving revision 1.30
diff -u -r1.30 ln.1
--- ln.1 16 Jan 2005 16:41:57 -0000 1.30
+++ ln.1 13 Feb 2006 18:15:21 -0000
@@ -41,11 +41,11 @@
.Nd make links
.Sh SYNOPSIS
.Nm
-.Op Fl fhinsv
+.Op Fl fFhinsv
.Ar source_file
.Op Ar target_file
.Nm
-.Op Fl fhinsv
+.Op Fl fFhinsv
.Ar source_file ...
.Ar target_dir
.Nm link
@@ -76,6 +76,16 @@
option overrides any previous
.Fl i
options.)
+.It Fl F
+This implies
+.Fl f
+option and will remove the target even if it is empty directory and
+.Fl s
+option is supplied also. No attempt to remove the target directory
+is performed when
+.Fl s
+option is omitted. This is most useful with two non-option arguments
+to create a symbolic link to the source directory.
.It Fl h
If the
.Ar target_file
@@ -99,6 +109,8 @@
.Fl i
option overrides any previous
.Fl f
+and
+.Fl F
options.)
.It Fl n
Same as
@@ -179,6 +191,10 @@
They are provided solely for compatibility with other
.Nm
implementations.
+.Pp
+The
+.Fl F
+option is FreeBSD extention and should not be used in portable scripts.
.Sh SEE ALSO
.Xr link 2 ,
.Xr lstat 2 ,
Index: ln.c
===================================================================
RCS file: /home/ncvs/src/bin/ln/ln.c,v
retrieving revision 1.33
diff -u -r1.33 ln.c
--- ln.c 9 Feb 2005 17:37:37 -0000 1.33
+++ ln.c 13 Feb 2006 18:17:56 -0000
@@ -53,6 +53,7 @@
#include <unistd.h>
int fflag; /* Unlink existing files. */
+int Fflag; /* Remove existing empty directories also. */
int hflag; /* Check new name for symlink first. */
int iflag; /* Interactive mode. */
int sflag; /* Symbolic, not hard, link. */
@@ -91,8 +92,11 @@
exit(linkit(argv[0], argv[1], 0));
}
- while ((ch = getopt(argc, argv, "fhinsv")) != -1)
+ while ((ch = getopt(argc, argv, "fFhinsv")) != -1)
switch (ch) {
+ case 'F':
+ Fflag = 1;
+ /* FALLTHROUGH */
case 'f':
fflag = 1;
iflag = 0;
@@ -104,6 +108,7 @@
case 'i':
iflag = 1;
fflag = 0;
+ Fflag = 0;
break;
case 's':
sflag = 1;
@@ -121,6 +126,8 @@
linkf = sflag ? symlink : link;
linkch = sflag ? '-' : '=';
+ if (!sflag)
+ Fflag = 0;
switch(argc) {
case 0:
@@ -198,9 +205,17 @@
/*
* If the file exists, then unlink it forcibly if -f was specified
* and interactively if -i was specified.
+ *
+ * For the directory, remove it only when -F and -s were specified.
*/
if (fflag && exists) {
- if (unlink(source)) {
+ if (Fflag && S_ISDIR(sb.st_mode)) {
+ if (rmdir(source)) {
+ warn("%s", source);
+ return (1);
+ }
+ }
+ else if (unlink(source)) {
warn("%s", source);
return (1);
}
@@ -236,8 +251,8 @@
usage(void)
{
(void)fprintf(stderr, "%s\n%s\n%s\n",
- "usage: ln [-fhinsv] source_file [target_file]",
- " ln [-fhinsv] source_file ... target_dir",
+ "usage: ln [-fFhinsv] source_file [target_file]",
+ " ln [-fFhinsv] source_file ... target_dir",
" link source_file target_file");
exit(1);
}
More information about the freebsd-bugs
mailing list