Subject: bin/23870: humanize ls(1)
To: None <gnats-bugs@gnats.netbsd.org>
From: None <daver@metropolis.localnet.gomerbud.com>
List: netbsd-bugs
Date: 12/24/2003 01:30:37
>Number: 23870
>Category: bin
>Synopsis: humanize ls(1)
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: bin-bug-people
>State: open
>Class: change-request
>Submitter-Id: net
>Arrival-Date: Wed Dec 24 12:21:00 UTC 2003
>Closed-Date:
>Last-Modified:
>Originator: David P. Reese Jr.
>Release: NetBSD 1.6ZG
>Organization:
>Environment:
System: NetBSD metropolis.localnet.gomerbud.com 1.6ZG NetBSD 1.6ZG (METROPOLIS) #8: Sun Dec 21 02:03:41 PST 2003 daver@metropolis.localnet.gomerbud.com:/home/daver/netbsd/src/sys/arch/i386/compile/METROPOLIS i386
Architecture: i386
Machine: i386
>Description:
ls(1) does not yet humanize it's output.
>How-To-Repeat:
man 1 ls
>Fix:
Index: ls.1
===================================================================
RCS file: /cvsroot/src/bin/ls/ls.1,v
retrieving revision 1.46
diff -u -u -r1.46 ls.1
--- ls.1 2003/09/22 06:01:43 1.46
+++ ls.1 2003/12/24 12:18:43
@@ -40,7 +40,7 @@
.Nd list directory contents
.Sh SYNOPSIS
.Nm
-.Op Fl AaBbCcdFfgikLlmnopqRrSsTtuWwx1
+.Op Fl AaBbCcdFfghikLlmnopqRrSsTtuWwx1
.Op Ar
.Sh DESCRIPTION
For each operand that names a
@@ -117,6 +117,13 @@
The same as
.Fl l ,
except that the owner is not printed.
+.It Fl h
+Modifies the
+.Fl s
+and
+.Fl l
+options, causing the sizes to be reported in bytes displayed in a human
+readable format.
.It Fl i
For each file, print the file's file serial number (inode number).
.It Fl k
Index: ls.c
===================================================================
RCS file: /cvsroot/src/bin/ls/ls.c,v
retrieving revision 1.52
diff -u -u -r1.52 ls.c
--- ls.c 2003/09/22 02:43:20 1.52
+++ ls.c 2003/12/24 12:18:43
@@ -88,6 +88,7 @@
int f_columnacross; /* columnated format, sorted across */
int f_flags; /* show flags associated with a file */
int f_grouponly; /* long listing without owner */
+int f_humanize; /* humanize the size field */
int f_inode; /* print inode */
int f_listdir; /* list actual directory, not contents */
int f_listdot; /* list files beginning with . */
@@ -135,7 +136,7 @@
f_listdot = 1;
fts_options = FTS_PHYSICAL;
- while ((ch = getopt(argc, argv, "1ABCFLRSTWabcdfgiklmnopqrstuwx")) != -1) {
+ while ((ch = getopt(argc, argv, "1ABCFLRSTWabcdfghiklmnopqrstuwx")) != -1) {
switch (ch) {
/*
* The -1, -C, -l, -m and -x options all override each other so
@@ -223,6 +224,13 @@
blocksize = 1024;
kflag = 1;
break;
+ /*
+ * The -h option forces all sizes to be measured in bytes.
+ * It also makes -l suppress -s.
+ */
+ case 'h':
+ f_humanize = 1;
+ break;
case 'n':
f_numericonly = 1;
break;
@@ -442,7 +450,7 @@
DISPLAY d;
FTSENT *cur;
NAMES *np;
- u_int64_t btotal, maxblock, maxsize;
+ u_int64_t btotal, stotal, maxblock, maxsize;
int maxinode, maxnlink, maxmajor, maxminor;
int bcfile, entries, flen, glen, ulen, maxflags, maxgroup, maxlen;
int maxuser, needstats;
@@ -471,7 +479,7 @@
maxinode = maxnlink = 0;
bcfile = 0;
maxuser = maxgroup = maxflags = maxlen = 0;
- btotal = maxblock = maxsize = 0;
+ btotal = stotal = maxblock = maxsize = 0;
maxmajor = maxminor = 0;
for (cur = list, entries = 0; cur; cur = cur->fts_link) {
if (cur->fts_info == FTS_ERR || cur->fts_info == FTS_NS) {
@@ -520,6 +528,7 @@
}
btotal += sp->st_blocks;
+ stotal += sp->st_size;
if (f_longform) {
if (f_numericonly ||
(user = user_from_uid(sp->st_uid, 0)) ==
@@ -574,17 +583,24 @@
d.maxlen = maxlen;
if (needstats) {
d.btotal = btotal;
- (void)snprintf(buf, sizeof(buf), "%llu",
- (long long)howmany(maxblock, blocksize));
- d.s_block = strlen(buf);
+ d.stotal = stotal;
+ if (!f_humanize) {
+ (void)snprintf(buf, sizeof(buf), "%llu",
+ (long long)howmany(maxblock, blocksize));
+ d.s_block = strlen(buf);
+ }
d.s_flags = maxflags;
d.s_group = maxgroup;
(void)snprintf(buf, sizeof(buf), "%u", maxinode);
d.s_inode = strlen(buf);
(void)snprintf(buf, sizeof(buf), "%u", maxnlink);
d.s_nlink = strlen(buf);
- (void)snprintf(buf, sizeof(buf), "%llu", (long long)maxsize);
- d.s_size = strlen(buf);
+ if (f_humanize) {
+ d.s_size = 4; /* min buffer length for humanize_number */
+ } else {
+ (void)snprintf(buf, sizeof(buf), "%llu", (long long)maxsize);
+ d.s_size = strlen(buf);
+ }
d.s_user = maxuser;
if (bcfile) {
(void)snprintf(buf, sizeof(buf), "%u", maxmajor);
Index: ls.h
===================================================================
RCS file: /cvsroot/src/bin/ls/ls.h,v
retrieving revision 1.15
diff -u -u -r1.15 ls.h
--- ls.h 2003/09/22 02:43:20 1.15
+++ ls.h 2003/12/24 12:18:43
@@ -41,6 +41,7 @@
extern int f_accesstime; /* use time of last access */
extern int f_flags; /* show flags associated with a file */
extern int f_grouponly; /* long listing without owner */
+extern int f_humanize; /* humanize size field */
extern int f_inode; /* print inode */
extern int f_longform; /* long listing format */
extern int f_octal; /* print octal escapes for nongraphic characters */
@@ -55,6 +56,7 @@
typedef struct {
FTSENT *list;
u_int64_t btotal;
+ u_int64_t stotal;
int entries;
int maxlen;
int s_block;
Index: print.c
===================================================================
RCS file: /cvsroot/src/bin/ls/print.c,v
retrieving revision 1.37
diff -u -u -r1.37 print.c
--- print.c 2003/09/22 02:43:20 1.37
+++ print.c 2003/12/24 12:18:46
@@ -55,6 +55,7 @@
#include <time.h>
#include <tzfile.h>
#include <unistd.h>
+#include <util.h>
#include "ls.h"
#include "extern.h"
@@ -89,13 +90,22 @@
struct stat *sp;
FTSENT *p;
NAMES *np;
- char buf[20];
+ char buf[20], szbuf[5];
now = time(NULL);
- if (dp->list->fts_level != FTS_ROOTLEVEL && (f_longform || f_size))
- (void)printf("total %llu\n",
- (long long)(howmany(dp->btotal, blocksize)));
+ if (dp->list->fts_level != FTS_ROOTLEVEL && (f_longform || f_size)) {
+ if (f_humanize) {
+ if ((humanize_number(szbuf, sizeof(szbuf), dp->stotal,
+ "", HN_AUTOSCALE,
+ (HN_DECIMAL | HN_B | HN_NOSPACE))) == -1)
+ err(1, "humanize_number");
+ (void)printf("total %s\n", szbuf);
+ } else {
+ (void)printf("total %llu\n",
+ (long long)(howmany(dp->btotal, blocksize)));
+ }
+ }
for (p = dp->list; p; p = p->fts_link) {
if (IS_NOPRINT(p))
@@ -104,9 +114,10 @@
if (f_inode)
(void)printf("%*lu ", dp->s_inode,
(unsigned long)sp->st_ino);
- if (f_size)
+ if (f_size && !f_humanize) {
(void)printf("%*llu ", dp->s_block,
(long long)howmany(sp->st_blocks, blocksize));
+ }
(void)strmode(sp->st_mode, buf);
np = p->fts_pointer;
(void)printf("%s %*lu ", buf, dp->s_nlink,
@@ -121,8 +132,16 @@
dp->s_major, major(sp->st_rdev), dp->s_minor,
minor(sp->st_rdev));
else
- (void)printf("%*llu ", dp->s_size,
- (long long)sp->st_size);
+ if (f_humanize) {
+ if ((humanize_number(szbuf, sizeof(szbuf),
+ sp->st_size, "", HN_AUTOSCALE,
+ (HN_DECIMAL | HN_B | HN_NOSPACE))) == -1)
+ err(1, "humanize_number");
+ (void)printf("%*s ", dp->s_size, szbuf);
+ } else {
+ (void)printf("%*llu ", dp->s_size,
+ (long long)sp->st_size);
+ }
if (f_accesstime)
printtime(sp->st_atime);
else if (f_statustime)
@@ -152,12 +171,17 @@
FTSENT *p;
int base, chcnt, col, colwidth, num;
int numcols, numrows, row;
+ char szbuf[5];
colwidth = dp->maxlen;
if (f_inode)
colwidth += dp->s_inode + 1;
- if (f_size)
- colwidth += dp->s_block + 1;
+ if (f_size) {
+ if (f_humanize)
+ colwidth += dp->s_size + 1;
+ else
+ colwidth += dp->s_block + 1;
+ }
if (f_type || f_typedir)
colwidth += 1;
@@ -190,13 +214,22 @@
if (num % numcols)
++numrows;
- if (dp->list->fts_level != FTS_ROOTLEVEL && (f_longform || f_size))
- (void)printf("total %llu\n",
- (long long)(howmany(dp->btotal, blocksize)));
+ if (dp->list->fts_level != FTS_ROOTLEVEL && (f_longform || f_size)) {
+ if (f_humanize) {
+ if ((humanize_number(szbuf, sizeof(szbuf), dp->stotal,
+ "", HN_AUTOSCALE,
+ (HN_DECIMAL | HN_B | HN_NOSPACE))) == -1)
+ err(1, "humanize_number");
+ (void)printf("total %s\n", szbuf);
+ } else {
+ (void)printf("total %llu\n",
+ (long long)(howmany(dp->btotal, blocksize)));
+ }
+ }
for (row = 0; row < numrows; ++row) {
for (base = row, chcnt = col = 0; col < numcols; ++col) {
chcnt = printaname(array[base], dp->s_inode,
- dp->s_block);
+ f_humanize ? dp->s_size : dp->s_block);
if ((base += numrows) >= num)
break;
while (chcnt++ < colwidth)
@@ -212,12 +245,17 @@
FTSENT *p;
int chcnt, col, colwidth;
int numcols;
+ char szbuf[5];
colwidth = dp->maxlen;
if (f_inode)
colwidth += dp->s_inode + 1;
- if (f_size)
- colwidth += dp->s_block + 1;
+ if (f_size) {
+ if (f_humanize)
+ colwidth += dp->s_size + 1;
+ else
+ colwidth += dp->s_block + 1;
+ }
if (f_type || f_typedir)
colwidth += 1;
@@ -231,9 +269,18 @@
numcols = termwidth / colwidth;
colwidth = termwidth / numcols; /* spread out if possible */
- if (dp->list->fts_level != FTS_ROOTLEVEL && (f_longform || f_size))
- (void)printf("total %llu\n",
- (long long)(howmany(dp->btotal, blocksize)));
+ if (dp->list->fts_level != FTS_ROOTLEVEL && (f_longform || f_size)) {
+ if (f_humanize) {
+ if ((humanize_number(szbuf, sizeof(szbuf), dp->stotal,
+ "", HN_AUTOSCALE,
+ (HN_DECIMAL | HN_B | HN_NOSPACE))) == -1)
+ err(1, "humanize_number");
+ (void)printf("total %s\n", szbuf);
+ } else {
+ (void)printf("total %llu\n",
+ (long long)(howmany(dp->btotal, blocksize)));
+ }
+ }
chcnt = col = 0;
for (p = dp->list; p; p = p->fts_link) {
if (IS_NOPRINT(p))
@@ -242,7 +289,8 @@
chcnt = col = 0;
(void)putchar('\n');
}
- chcnt = printaname(p, dp->s_inode, dp->s_block);
+ chcnt = printaname(p, dp->s_inode,
+ f_humanize ? dp->s_size : dp->s_block);
while (chcnt++ < colwidth)
(void)putchar(' ');
col++;
@@ -260,8 +308,12 @@
extwidth = 0;
if (f_inode)
extwidth += dp->s_inode + 1;
- if (f_size)
- extwidth += dp->s_block + 1;
+ if (f_size) {
+ if (f_humanize)
+ extwidth += dp->s_size + 1;
+ else
+ extwidth += dp->s_block + 1;
+ }
if (f_type)
extwidth += 1;
@@ -275,7 +327,8 @@
else
(void)putchar(' '), col++;
}
- col += printaname(p, dp->s_inode, dp->s_block);
+ col += printaname(p, dp->s_inode,
+ f_humanize ? dp->s_size : dp->s_block);
}
(void)putchar('\n');
}
@@ -289,14 +342,24 @@
{
struct stat *sp;
int chcnt;
+ char szbuf[5];
sp = p->fts_statp;
chcnt = 0;
if (f_inode)
chcnt += printf("%*lu ", inodefield, (unsigned long)sp->st_ino);
- if (f_size)
- chcnt += printf("%*llu ", sizefield,
- (long long)howmany(sp->st_blocks, blocksize));
+ if (f_size) {
+ if (f_humanize) {
+ if ((humanize_number(szbuf, sizeof(szbuf), sp->st_size,
+ "", HN_AUTOSCALE,
+ (HN_DECIMAL | HN_B | HN_NOSPACE))) == -1)
+ err(1, "humanize_number");
+ chcnt += printf("%*s ", sizefield, szbuf);
+ } else {
+ chcnt += printf("%*llu ", sizefield,
+ (long long)howmany(sp->st_blocks, blocksize));
+ }
+ }
if (f_octal || f_octal_escape)
chcnt += safe_print(p->fts_name);
else if (f_nonprint)
>Release-Note:
>Audit-Trail:
>Unformatted: