svn commit: r216203 - head/usr.bin/stat

Doug Barton dougb at FreeBSD.org
Sun Dec 5 21:11:46 UTC 2010


Author: dougb
Date: Sun Dec  5 21:11:45 2010
New Revision: 216203
URL: http://svn.freebsd.org/changeset/base/216203

Log:
  Bring in a new feature, adding a -f option to readlink to print the path
  of the target, similar to realpath(1). See the discussion at:
  http://gnats.netbsd.org/cgi-bin/query-pr-single.pl?number=34662
  
  This brings in the following changes:
  1.24
  "PR/34662: martijnb at atlas dot ipv6 dot stack dot nl: readlink doesn't
  grok -f, and there's no alternative (+fix)
  
  Patch applied with minor tweak (%y -> %R, as it was already taken) plus
  some nits from myself. Thanks!"
  
  Obtained from:	elad at NetBSD.org
  
  1.25
  "Fix a segfault when doing 'stat -f %R' on the stdin file handle, instead
  fake the filename '(stdin)' like the %N format."
  
  Obtained from:	mlelstv at NetBSD.org
  
  1.27
  "The ofmt variable is actually a bit mask (not the character that was
  in the format string) so that we can "or" it with the bits in the
  formats variable.  This fixes the missing " -> " in front of the real
  path (when you use %SR).
  
  Also, the ?: needs another space."
  
  Obtained from:	atatat at NetBSD.org
  
  I am purposely omitting the following changes:
  1.23	A humanize_number(3) clone that should better be implemented by
  	actually using humanize_number(3)
  1.26	This is the removal of license clause 3 and 4, already handled
  	by imp in r203971

Modified:
  head/usr.bin/stat/stat.c

Modified: head/usr.bin/stat/stat.c
==============================================================================
--- head/usr.bin/stat/stat.c	Sun Dec  5 20:47:53 2010	(r216202)
+++ head/usr.bin/stat/stat.c	Sun Dec  5 21:11:45 2010	(r216203)
@@ -30,7 +30,7 @@
 #include <sys/cdefs.h>
 #if 0
 #ifndef lint
-__RCSID("$NetBSD: stat.c,v 1.22 2005/04/22 03:36:48 atatat Exp $");
+__RCSID("$NetBSD: stat.c,v 1.27 2008/05/16 17:58:33 atatat Exp $");
 #endif
 #endif
 
@@ -153,6 +153,7 @@ __FBSDID("$FreeBSD$");
 #define MIDDLE_PIECE	'M'
 #define LOW_PIECE	'L'
 
+#define	SHOW_realpath	'R'
 #define SHOW_st_dev	'd'
 #define SHOW_st_ino	'i'
 #define SHOW_st_mode	'p'
@@ -218,8 +219,8 @@ main(int argc, char *argv[])
 
 	if (strcmp(getprogname(), "readlink") == 0) {
 		am_readlink = 1;
-		options = "n";
-		synopsis = "[-n] [file ...]";
+		options = "fn";
+		synopsis = "[-fn] [file ...]";
 		statfmt = "%Y";
 		fmtchar = 'f';
 		quiet = 1;
@@ -243,6 +244,10 @@ main(int argc, char *argv[])
 			quiet = 1;
 			break;
 		case 'f':
+			if (am_readlink) {
+				statfmt = "%R";
+				break;
+			}
 			statfmt = optarg;
 			/* FALLTHROUGH */
 		case 'l':
@@ -518,6 +523,7 @@ output(const struct stat *st, const char
 		}
 
 		switch (*statfmt) {
+			fmtcase(what, SHOW_realpath);
 			fmtcase(what, SHOW_st_dev);
 			fmtcase(what, SHOW_st_ino);
 			fmtcase(what, SHOW_st_mode);
@@ -776,6 +782,26 @@ format1(const struct stat *st,
 			ofmt = FMTF_UNSIGNED;
 		break;
 #endif /* HAVE_STRUCT_STAT_ST_GEN */
+	case SHOW_realpath:
+		small = 0;
+		data = 0;
+		if (file == NULL) {
+			(void)strncpy(path, "(stdin)", sizeof(path));
+			sdata = path;
+		} else {
+			snprintf(path, sizeof(path), " -> ");
+			if (realpath(file, path + 4) == NULL) {
+				linkfail = 1;
+				l = 0;
+				path[0] = '\0';
+			}
+			sdata = path + (ofmt == FMTF_STRING ? 0 : 4);
+		}
+
+		formats = FMTF_STRING;
+		if (ofmt == 0)
+			ofmt = FMTF_STRING;
+		break;
 	case SHOW_symlink:
 		small = 0;
 		data = 0;


More information about the svn-src-all mailing list