From owner-freebsd-bugs@FreeBSD.ORG Sun Jan 22 13:50:24 2006 Return-Path: X-Original-To: freebsd-bugs@hub.freebsd.org Delivered-To: freebsd-bugs@hub.freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id F214B16A41F for ; Sun, 22 Jan 2006 13:50:23 +0000 (GMT) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [216.136.204.21]) by mx1.FreeBSD.org (Postfix) with ESMTP id E3E1343D76 for ; Sun, 22 Jan 2006 13:50:04 +0000 (GMT) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) by freefall.freebsd.org (8.13.4/8.13.4) with ESMTP id k0MDo3Ou004129 for ; Sun, 22 Jan 2006 13:50:03 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.13.4/8.13.4/Submit) id k0MDo32Y004126; Sun, 22 Jan 2006 13:50:03 GMT (envelope-from gnats) Resent-Date: Sun, 22 Jan 2006 13:50:03 GMT Resent-Message-Id: <200601221350.k0MDo32Y004126@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-bugs@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, Eugene Grosbein Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id D7D0516A420 for ; Sun, 22 Jan 2006 13:43:52 +0000 (GMT) (envelope-from eugen@ws092.svzserv.kemerovo.su) Received: from ws092.svzserv.kemerovo.su (kost.svzserv.kemerovo.su [213.184.65.82]) by mx1.FreeBSD.org (Postfix) with ESMTP id EC00F43D45 for ; Sun, 22 Jan 2006 13:43:51 +0000 (GMT) (envelope-from eugen@ws092.svzserv.kemerovo.su) Received: from ws092.svzserv.kemerovo.su (localhost [127.0.0.1]) by ws092.svzserv.kemerovo.su (8.13.4/8.13.4) with ESMTP id k0MDhU4F048464 for ; Sun, 22 Jan 2006 20:43:30 +0700 (KRAT) (envelope-from eugen@ws092.svzserv.kemerovo.su) Received: (from root@localhost) by ws092.svzserv.kemerovo.su (8.13.4/8.13.3/Submit) id k0MDh9xq048442; Sun, 22 Jan 2006 20:43:09 +0700 (KRAT) (envelope-from eugen) Message-Id: <200601221343.k0MDh9xq048442@ws092.svzserv.kemerovo.su> Date: Sun, 22 Jan 2006 20:43:09 +0700 (KRAT) From: Eugene Grosbein To: FreeBSD-gnats-submit@FreeBSD.org X-Send-Pr-Version: 3.113 Cc: Subject: bin/92149: [patch] ln -f -s does not remove existing directory X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: Eugene Grosbein List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 22 Jan 2006 13:50:24 -0000 >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@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: