bin/92149: [patch] ln -f -s does not remove existing directory
Eugene Grosbein
eugen at grosbein.pp.ru
Sun Jan 22 05:50:24 PST 2006
>Number: 92149
>Category: bin
>Synopsis: [patch] ln -f -s does not remove existing directory
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: change-request
>Submitter-Id: current-users
>Arrival-Date: Sun Jan 22 13:50:02 GMT 2006
>Closed-Date:
>Last-Modified:
>Originator: Eugene Grosbein
>Release: FreeBSD 6.0-STABLE i386
>Organization:
Svyaz-Service JSC
>Environment:
System: FreeBSD ws092.svzserv.kemerovo.su 6.0-STABLE FreeBSD 6.0-STABLE #6: Tue Dec 27 22:06:20 KRAT 2005 eugen at ws092.svzserv.kemerovo.su:/usr/obj/usr/src/sys/TEST i386
>Description:
"ln -f -s" may be used to create a symlink to the file and
the target file will be unlinked if it exists.
However, ln will fail with 'Operation not permitted' message
when target is a directory because unlink(2) does not remove
empty directories.
>How-To-Repeat:
mkdir -p dir/etc
ln -f -s /etc dir
>Fix:
The following patch allows ln(1) to remove existing target
if the -s option is supplied and the target is the (empty) directory.
The patch is for src/bin/ln:
--- ln.c.orig Sun Jan 22 20:05:44 2006
+++ ln.c Sun Jan 22 20:28:10 2006
@@ -198,8 +198,16 @@
/*
* If the file exists, then unlink it forcibly if -f was specified
* and interactively if -i was specified.
+ *
+ * For the directory, remove it when dealing with symbolic link only.
*/
if (fflag && exists) {
+ if (sflag && rmdir(source)) {
+ if (errno != ENOTDIR) {
+ warn("%s", source);
+ return (1);
+ }
+ }
if (unlink(source)) {
warn("%s", source);
return (1);
@@ -216,6 +224,12 @@
return (1);
}
+ if (sflag && rmdir(source)) {
+ if (errno != ENOTDIR) {
+ warn("%s", source);
+ return (1);
+ }
+ }
if (unlink(source)) {
warn("%s", source);
return (1);
--- ln.1.orig Sun Jan 22 20:18:12 2006
+++ ln.1 Sun Jan 22 20:36:06 2006
@@ -69,8 +69,12 @@
The options are as follows:
.Bl -tag -width flag
.It Fl f
-If the target file already exists,
-then unlink it so that the link may occur.
+If the target file or directory already exists,
+then remove it so that the link may occur.
+Note that no attempt to remove the directory is performed
+when running without the
+.Fl s
+option.
(The
.Fl f
option overrides any previous
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-bugs
mailing list