[PATCH] flexi-size column for ls

Ian Wienand ianw at vmware.com
Mon Sep 28 23:33:45 UTC 2009


Hi,

Although it sounds a little ridiculous for embedded systems, with the
advent of big-disk NAS systems etc it's probably quite easy to
overflow the 9 characters for the file size in ls.  We noticed when
people tried ls against tb sized files on VMFS partitions.

This implements a flexi-size for the size field.  Although other
fields could also be made flexi, it seems they're less likely to
expand past their limits.

e.g.

$ ./busybox ls -l b*
-rw-r--r--    1 2049807  201     1073741824 Sep 28 16:14 big
-rwxr-xr-x    1 2049807  201         855368 Sep 28 16:13 busybox
-rwxr-xr-x    1 2049807  201         999754 Sep 28 16:22 busybox_old
-rwxr-xr-x    1 2049807  201         999898 Sep 28 16:22 busybox_unstripped
-rw-r--r--    1 2049807  201         935299 Sep 28 16:22 busybox_unstripped.map
-rw-r--r--    1 2049807  201          28077 Sep 28 16:22 busybox_unstripped.out
$ ./busybox ls -lh b*
-rw-r--r--    1 2049807  201       1.0G Sep 28 16:14 big
-rwxr-xr-x    1 2049807  201     835.3K Sep 28 16:13 busybox
-rwxr-xr-x    1 2049807  201     976.3K Sep 28 16:22 busybox_old
-rwxr-xr-x    1 2049807  201     976.5K Sep 28 16:22 busybox_unstripped
-rw-r--r--    1 2049807  201     913.4K Sep 28 16:22 busybox_unstripped.map
-rw-r--r--    1 2049807  201      27.4K Sep 28 16:22 busybox_unstripped.out

function                                             old     new   delta
showfiles                                           1418    1555    +137
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/0 up/down: 137/0)             Total: 137 bytes
    text	   data	    bss	    dec	    hex	filename
  848473	   4254	   9736	 862463	  d28ff	busybox_old
  848615	   4254	   9736	 862605	  d298d	busybox_unstripped

---

diff --git a/coreutils/ls.c b/coreutils/ls.c
index 827b350..44d585d 100644
--- a/coreutils/ls.c
+++ b/coreutils/ls.c
@@ -244,7 +244,7 @@ struct dnode {                  /* the basic node */

  static struct dnode **list_dir(const char *);
  static struct dnode **dnalloc(int);
-static int list_single(const struct dnode *);
+static int list_single(const struct dnode *, int);


  struct globals {
@@ -548,11 +548,32 @@ static void showfiles(struct dnode **dn, int nfiles)
  	int nexttab = 0;
  	int column_width = 0; /* for STYLE_LONG and STYLE_SINGLE not used */

+	int size_width = 0;
+
  	if (dn == NULL || nfiles < 1)
  		return;

  	if (all_fmt & STYLE_LONG) {
  		ncols = 1;
+
+		/* find the longest file size */
+		for (i = 0; i < nfiles; i++) {
+		  int w;
+		  if (all_fmt & LS_DISP_HR) {
+		    w = bb_mbstrlen(make_human_readable_str(dn[i]->dstat.st_size, 1, 0));
+		  } else {
+		    off_t s = dn[i]->dstat.st_size;
+		    w = 2; // 1 + 1 for padding
+		    while (s > 10) {
+		      w++; s /= 10;
+		    }
+		  }
+
+		  if (w > size_width) {
+		    size_width = w;
+		  }
+		}
+	
  	} else {
  		/* find the longest file name, use that as the column width */
  		for (i = 0; i < nfiles; i++) {
@@ -589,7 +610,7 @@ static void showfiles(struct dnode **dn, int nfiles)
  					column += nexttab;
  				}
  				nexttab = column + column_width;
-				column += list_single(dn[i]);
+				column += list_single(dn[i], size_width);
  			}
  		}
  		putchar('\n');
@@ -730,7 +751,8 @@ static int print_name(const char *name)
  }


-static int list_single(const struct dnode *dn)
+static int list_single(const struct dnode *dn,
+		       int size_width)
  {
  	int column = 0;
  	char *lpath = lpath; /* for compiler */
@@ -799,10 +821,13 @@ static int list_single(const struct dnode *dn)
  					(int) minor(dn->dstat.st_rdev));
  		} else {
  			if (all_fmt & LS_DISP_HR) {
-				column += printf("%9s ",
-					make_human_readable_str(dn->dstat.st_size, 1, 0));
+				column += printf("%*s ",
+						 size_width,
+						 make_human_readable_str(dn->dstat.st_size, 1, 0));
  			} else {
-				column += printf("%9"OFF_FMT"u ", (off_t) dn->dstat.st_size);
+				column += printf("%*"OFF_FMT"u ",
+						 size_width,
+						 (off_t) dn->dstat.st_size);
  			}
  		}
  	}


More information about the busybox mailing list