Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 13 Feb 2006 18:30:11 GMT
From:      Eugene Grosbein <eugen@grosbein.pp.ru>
To:        freebsd-bugs@FreeBSD.org
Subject:   Re: bin/92149 : [patch] ln(1): ln -f -s does not remove existing directory
Message-ID:  <200602131830.k1DIUBbF005528@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help
The following reply was made to PR bin/92149; it has been noted by GNATS.

From: Eugene Grosbein <eugen@grosbein.pp.ru>
To: bug-followup@freebsd.org
Cc: Gleb Smirnoff <glebius@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);
  }



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200602131830.k1DIUBbF005528>