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>