svn commit: r202945 - head/bin/ls

Jaakko Heinonen jh at FreeBSD.org
Sun Jan 24 19:23:08 UTC 2010


Author: jh
Date: Sun Jan 24 19:23:07 2010
New Revision: 202945
URL: http://svn.freebsd.org/changeset/base/202945

Log:
  Fixes for ls(1) long format (-l) output:
  
  - Allow -h option to work if the listing contains at least one device
    file.
  - Align major and minor device numbers correctly to the size field.
  
  PR:		bin/125678
  Approved by:	trasz (mentor)
  MFC after:	1 month

Modified:
  head/bin/ls/ls.c
  head/bin/ls/ls.h
  head/bin/ls/print.c

Modified: head/bin/ls/ls.c
==============================================================================
--- head/bin/ls/ls.c	Sun Jan 24 19:17:35 2010	(r202944)
+++ head/bin/ls/ls.c	Sun Jan 24 19:23:07 2010	(r202945)
@@ -559,7 +559,8 @@ display(const FTSENT *p, FTSENT *list, i
 	long maxblock;
 	u_long btotal, labelstrlen, maxinode, maxlen, maxnlink;
 	u_long maxlabelstr;
-	int bcfile, maxflags;
+	u_int devstrlen;
+	int maxflags;
 	gid_t maxgroup;
 	uid_t maxuser;
 	size_t flen, ulen, glen;
@@ -651,7 +652,7 @@ display(const FTSENT *p, FTSENT *list, i
 		MAKENINES(maxsize);
 		free(jinitmax);
 	}
-	bcfile = 0;
+	devstrlen = 0;
 	flags = NULL;
 	for (cur = list, entries = 0; cur; cur = cur->fts_link) {
 		if (cur->fts_info == FTS_ERR || cur->fts_info == FTS_NS) {
@@ -791,9 +792,15 @@ label_out:
 				np->group = &np->data[ulen + 1];
 				(void)strcpy(np->group, group);
 
-				if (S_ISCHR(sp->st_mode) ||
-				    S_ISBLK(sp->st_mode))
-					bcfile = 1;
+				if ((S_ISCHR(sp->st_mode) ||
+				    S_ISBLK(sp->st_mode)) &&
+				    devstrlen < DEVSTR_HEX_LEN) {
+					if (minor(sp->st_rdev) > 255 ||
+					    minor(sp->st_rdev) < 0)
+						devstrlen = DEVSTR_HEX_LEN;
+					else
+						devstrlen = DEVSTR_LEN;
+				}
 
 				if (f_flags) {
 					np->flags = &np->data[ulen + glen + 2];
@@ -825,7 +832,6 @@ label_out:
 	d.entries = entries;
 	d.maxlen = maxlen;
 	if (needstats) {
-		d.bcfile = bcfile;
 		d.btotal = btotal;
 		(void)snprintf(buf, sizeof(buf), "%lu", maxblock);
 		d.s_block = strlen(buf);
@@ -836,8 +842,14 @@ label_out:
 		d.s_inode = strlen(buf);
 		(void)snprintf(buf, sizeof(buf), "%lu", maxnlink);
 		d.s_nlink = strlen(buf);
-		(void)snprintf(buf, sizeof(buf), "%ju", maxsize);
-		d.s_size = strlen(buf);
+		if (f_humanval)
+			d.s_size = HUMANVALSTR_LEN;
+		else {
+			(void)snprintf(buf, sizeof(buf), "%ju", maxsize);
+			d.s_size = strlen(buf);
+		}
+		if (d.s_size < devstrlen)
+			d.s_size = devstrlen;
 		d.s_user = maxuser;
 	}
 	printfcn(&d);

Modified: head/bin/ls/ls.h
==============================================================================
--- head/bin/ls/ls.h	Sun Jan 24 19:17:35 2010	(r202944)
+++ head/bin/ls/ls.h	Sun Jan 24 19:23:07 2010	(r202945)
@@ -35,6 +35,10 @@
 
 #define NO_PRINT	1
 
+#define HUMANVALSTR_LEN	5
+#define DEVSTR_LEN	8
+#define DEVSTR_HEX_LEN	15
+
 extern long blocksize;		/* block size units */
 
 extern int f_accesstime;	/* use time of last access */
@@ -62,7 +66,6 @@ extern int f_color;		/* add type in colo
 typedef struct {
 	FTSENT *list;
 	u_long btotal;
-	int bcfile;
 	int entries;
 	int maxlen;
 	u_int s_block;

Modified: head/bin/ls/print.c
==============================================================================
--- head/bin/ls/print.c	Sun Jan 24 19:17:35 2010	(r202944)
+++ head/bin/ls/print.c	Sun Jan 24 19:23:07 2010	(r202945)
@@ -62,6 +62,7 @@ __FBSDID("$FreeBSD$");
 #include "extern.h"
 
 static int	printaname(const FTSENT *, u_long, u_long);
+static void	printdev(size_t, dev_t);
 static void	printlink(const FTSENT *);
 static void	printtime(time_t);
 static int	printtype(u_int);
@@ -165,16 +166,7 @@ printlong(const DISPLAY *dp)
 		if (f_label)
 			(void)printf("%-*s ", dp->s_label, np->label);
 		if (S_ISCHR(sp->st_mode) || S_ISBLK(sp->st_mode))
-			if (minor(sp->st_rdev) > 255 || minor(sp->st_rdev) < 0)
-				(void)printf("%3d, 0x%08x ",
-				    major(sp->st_rdev),
-				    (u_int)minor(sp->st_rdev));
-			else
-				(void)printf("%3d, %3d ",
-				    major(sp->st_rdev), minor(sp->st_rdev));
-		else if (dp->bcfile)
-			(void)printf("%*s%*jd ",
-			    8 - dp->s_size, "", dp->s_size, sp->st_size);
+			printdev(dp->s_size, sp->st_rdev);
 		else
 			printsize(dp->s_size, sp->st_size);
 		if (f_accesstime)
@@ -353,6 +345,24 @@ printaname(const FTSENT *p, u_long inode
 	return (chcnt);
 }
 
+/*
+ * Print device special file major and minor numbers.
+ */
+static void
+printdev(size_t width, dev_t dev)
+{
+	char buf[DEVSTR_HEX_LEN + 1];
+
+	if (minor(dev) > 255 || minor(dev) < 0)
+		(void)snprintf(buf, sizeof(buf), "%3d, 0x%08x",
+		    major(dev), (u_int)minor(dev));
+	else
+		(void)snprintf(buf, sizeof(buf), "%3d, %3d",
+		    major(dev), minor(dev));
+
+	(void)printf("%*s ", (u_int)width, buf);
+}
+
 static void
 printtime(time_t ftime)
 {
@@ -592,11 +602,15 @@ printsize(size_t width, off_t bytes)
 {
 
 	if (f_humanval) {
-		char buf[5];
+		/*
+		 * Reserve one space before the size and allocate room for
+		 * the trailing '\0'.
+		 */
+		char buf[HUMANVALSTR_LEN - 1 + 1];
 
 		humanize_number(buf, sizeof(buf), (int64_t)bytes, "",
 		    HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL);
-		(void)printf("%5s ", buf);
+		(void)printf("%*s ", (u_int)width, buf);
 	} else
 		(void)printf("%*jd ", (u_int)width, bytes);
 }


More information about the svn-src-head mailing list