svn commit: r187629 - stable/7/bin/ln

Giorgos Keramidas keramida at FreeBSD.org
Fri Jan 23 03:58:26 PST 2009


Author: keramida (doc committer)
Date: Fri Jan 23 11:58:24 2009
New Revision: 187629
URL: http://svn.freebsd.org/changeset/base/187629

Log:
  MFC 179603 and 179636 from /head
  
    Add a -w warning flag to ln(1).  When the -w option is enabled,
    ln(1) checks to see if the source of a symlink, i.e. the file it
    should point to actually exists.  The default is the old ln
    behavior, that does not check, to avoid surprising people who may
    be using ln(1) in scripts or other non-interactive places.
  
    PR:             bin/7265
    Submitted by:   Joel Ray Holveck, detlev!joelh at mail.camalott.com

Modified:
  stable/7/bin/ln/   (props changed)
  stable/7/bin/ln/ln.1
  stable/7/bin/ln/ln.c

Modified: stable/7/bin/ln/ln.1
==============================================================================
--- stable/7/bin/ln/ln.1	Fri Jan 23 11:54:31 2009	(r187628)
+++ stable/7/bin/ln/ln.1	Fri Jan 23 11:58:24 2009	(r187629)
@@ -32,7 +32,7 @@
 .\"	@(#)ln.1	8.2 (Berkeley) 12/30/93
 .\" $FreeBSD$
 .\"
-.Dd February 14, 2006
+.Dd June 6, 2008
 .Dt LN 1
 .Os
 .Sh NAME
@@ -42,13 +42,13 @@
 .Sh SYNOPSIS
 .Nm
 .Op Fl s Op Fl F
-.Op Fl f | i
+.Op Fl f | iw
 .Op Fl hnv
 .Ar source_file
 .Op Ar target_file
 .Nm
 .Op Fl s Op Fl F
-.Op Fl f | i
+.Op Fl f | iw
 .Op Fl hnv
 .Ar source_file ...
 .Ar target_dir
@@ -79,6 +79,8 @@ then unlink it so that the link may occu
 .Fl f
 option overrides any previous
 .Fl i
+and
+.Fl w
 options.)
 .It Fl F
 If the target file already exists and is a directory, then remove it
@@ -134,6 +136,8 @@ Create a symbolic link.
 Cause
 .Nm
 to be verbose, showing files as they are processed.
+.It Fl w
+Warn if the source of a symbolic link does not currently exist.
 .El
 .Pp
 By default,
@@ -194,9 +198,10 @@ operation using the two passed arguments
 The
 .Fl h ,
 .Fl i ,
-.Fl n
-and
+.Fl n ,
 .Fl v
+and
+.Fl w
 options are non-standard and their use in scripts is not recommended.
 They are provided solely for compatibility with other
 .Nm

Modified: stable/7/bin/ln/ln.c
==============================================================================
--- stable/7/bin/ln/ln.c	Fri Jan 23 11:54:31 2009	(r187628)
+++ stable/7/bin/ln/ln.c	Fri Jan 23 11:58:24 2009	(r187629)
@@ -58,6 +58,8 @@ int	hflag;				/* Check new name for syml
 int	iflag;				/* Interactive mode. */
 int	sflag;				/* Symbolic, not hard, link. */
 int	vflag;				/* Verbose output. */
+int	wflag;				/* Warn if symlink target does not
+					 * exist, and -f is not enabled. */
 					/* System link call. */
 int (*linkf)(const char *, const char *);
 char	linkch;
@@ -92,7 +94,7 @@ main(int argc, char *argv[])
 		exit(linkit(argv[0], argv[1], 0));
 	}
 
-	while ((ch = getopt(argc, argv, "Ffhinsv")) != -1)
+	while ((ch = getopt(argc, argv, "Ffhinsvw")) != -1)
 		switch (ch) {
 		case 'F':
 			Fflag = 1;
@@ -100,6 +102,7 @@ main(int argc, char *argv[])
 		case 'f':
 			fflag = 1;
 			iflag = 0;
+			wflag = 0;
 			break;
 		case 'h':
 		case 'n':
@@ -115,6 +118,9 @@ main(int argc, char *argv[])
 		case 'v':
 			vflag = 1;
 			break;
+		case 'w':
+			wflag = 1;
+			break;
 		case '?':
 		default:
 			usage();
@@ -127,8 +133,10 @@ main(int argc, char *argv[])
 	linkch = sflag ? '-' : '=';
 	if (sflag == 0)
 		Fflag = 0;
-	if (Fflag == 1 && iflag == 0)
+	if (Fflag == 1 && iflag == 0) {
 		fflag = 1;
+		wflag = 0;		/* Implied when fflag != 0 */
+	}
 
 	switch(argc) {
 	case 0:
@@ -167,6 +175,7 @@ linkit(const char *target, const char *s
 	const char *p;
 	int ch, exists, first;
 	char path[PATH_MAX];
+	char wbuf[PATH_MAX];
 
 	if (!sflag) {
 		/* If target doesn't exist, quit now. */
@@ -204,6 +213,32 @@ linkit(const char *target, const char *s
 
 	exists = !lstat(source, &sb);
 	/*
+	 * If the link source doesn't exist, and a symbolic link was
+	 * requested, and -w was specified, give a warning.
+	 */
+	if (sflag && wflag) {
+		if (*source == '/') {
+			/* Absolute link source. */
+			if (stat(source, &sb) != 0)
+				 warn("warning: %s inaccessible", source);
+		} else {
+			/*
+			 * Relative symlink source.  Try to construct the
+			 * absolute path of the source, by appending `source'
+			 * to the parent directory of the target.
+			 */
+			p = strrchr(target, '/');
+			if (p != NULL)
+				p++;
+			else
+				p = target;
+			(void)snprintf(wbuf, sizeof(wbuf), "%.*s%s",
+			    (int)(p - target), target, source);
+			if (stat(wbuf, &sb) != 0)
+				warn("warning: %s", source);
+		}
+	}
+	/*
 	 * If the file exists, then unlink it forcibly if -f was specified
 	 * and interactively if -i was specified.
 	 */


More information about the svn-src-stable-7 mailing list