aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorElliott Hughes <enh@google.com>2015-09-05 05:09:22 -0500
committerRob Landley <rob@landley.net>2015-09-05 05:09:22 -0500
commit091997e4c6f5655876a3133ae80b52c2d91a8216 (patch)
treec7c22a5e6f012c318e182b0ce884540b197393f9
parentc82343fe0bb293d3ed60b9122426f0bbcb0e58b0 (diff)
downloadtoybox-091997e4c6f5655876a3133ae80b52c2d91a8216.tar.gz
ls -h support.
It turns out that people are anticipating the switch to toybox ls from toolbox ls on the assumption that this will finally bring -h support. Let's not disappoint. I've merged two existing buffers in listfiles whose uses didn't overlap into one. It may be possible to cram this into toybuf with the other stuff, but it didn't seem worth the extra complexity for 64B of stack, especially since we were already living with that for time formatting anyway.
-rw-r--r--toys/posix/ls.c45
1 files changed, 29 insertions, 16 deletions
diff --git a/toys/posix/ls.c b/toys/posix/ls.c
index e46a5762..c815ab63 100644
--- a/toys/posix/ls.c
+++ b/toys/posix/ls.c
@@ -5,13 +5,13 @@
*
* See http://opengroup.org/onlinepubs/9699919799/utilities/ls.html
-USE_LS(NEWTOY(ls, USE_LS_COLOR("(color):;")"ZgoACFHLRSacdfiklmnpqrstux1[-Cxm1][-Cxml][-Cxmo][-Cxmg][-cu][-ftS][-HL]", TOYFLAG_BIN|TOYFLAG_LOCALE))
+USE_LS(NEWTOY(ls, USE_LS_COLOR("(color):;")"ZgoACFHLRSacdfhiklmnpqrstux1[-Cxm1][-Cxml][-Cxmo][-Cxmg][-cu][-ftS][-HL]", TOYFLAG_BIN|TOYFLAG_LOCALE))
config LS
bool "ls"
default y
help
- usage: ls [-ACFHLRSZacdfiklmnpqrstux1] [directory...]
+ usage: ls [-ACFHLRSZacdfhiklmnpqrstux1] [directory...]
list files
what to show:
@@ -26,9 +26,10 @@ config LS
output formats:
-1 list one file per line -C columns (sorted vertically)
- -g like -l but no owner -l long (show full details)
- -m comma separated -n like -l but numeric uid/gid
- -o like -l but no group -x columns (horizontal sort)
+ -g like -l but no owner -h human readable sizes
+ -l long (show full details) -m comma separated
+ -n like -l but numeric uid/gid -o like -l but no group
+ -x columns (horizontal sort)
sorting (default is alphabetical):
-f unsorted -r reverse -t timestamp -S size
@@ -127,6 +128,7 @@ static void entrylen(struct dirtree *dt, unsigned *len)
{
struct stat *st = &(dt->st);
unsigned flags = toys.optflags;
+ char tmp[64];
*len = strwidth(dt->name);
if (endtype(st)) ++*len;
@@ -142,6 +144,9 @@ static void entrylen(struct dirtree *dt, unsigned *len)
// cheating slightly here: assuming minor is always 3 digits to avoid
// tracking another column
len[5] = numlen(major(st->st_rdev))+5;
+ } else if (flags & FLAG_h) {
+ human_readable(tmp, st->st_size, 0);
+ len[5] = strwidth(tmp);
} else len[5] = numlen(st->st_size);
}
@@ -290,6 +295,7 @@ static void listfiles(int dirfd, struct dirtree *indir)
unsigned long dtlen, ul = 0;
unsigned width, flags = toys.optflags, totals[8], len[8], totpad = 0,
*colsizes = (unsigned *)(toybuf+260), columns = (sizeof(toybuf)-260)/4;
+ char tmp[64];
memset(totals, 0, sizeof(totals));
@@ -346,8 +352,12 @@ static void listfiles(int dirfd, struct dirtree *indir)
blocks += sort[ul]->st.st_blocks;
}
totpad = totals[1]+!!totals[1]+totals[6]+!!totals[6]+totals[7]+!!totals[7];
- if ((flags&(FLAG_l|FLAG_o|FLAG_n|FLAG_g|FLAG_s)) && indir->parent)
- xprintf("total %llu\n", blocks);
+ if ((flags&(FLAG_h|FLAG_l|FLAG_o|FLAG_n|FLAG_g|FLAG_s)) && indir->parent) {
+ if (flags&FLAG_h) {
+ human_readable(tmp, blocks*512, 0);
+ xprintf("total %s\n", tmp);
+ } else xprintf("total %llu\n", blocks);
+ }
}
// Find largest entry in each field for display alignment
@@ -416,22 +426,22 @@ static void listfiles(int dirfd, struct dirtree *indir)
if (flags & (FLAG_l|FLAG_o|FLAG_n|FLAG_g)) {
struct tm *tm;
- char perm[11], thyme[64], *ss;
+ char *ss;
// (long) is to coerce the st types into something we know we can print.
- mode_to_string(mode, perm);
- printf("%s% *ld", perm, totals[2]+1, (long)st->st_nlink);
+ mode_to_string(mode, tmp);
+ printf("%s% *ld", tmp, totals[2]+1, (long)st->st_nlink);
// print user
if (!(flags&FLAG_g)) {
- if (flags&FLAG_n) sprintf(ss = thyme, "%u", (unsigned)st->st_uid);
+ if (flags&FLAG_n) sprintf(ss = tmp, "%u", (unsigned)st->st_uid);
else strwidth(ss = getusername(st->st_uid));
printf(" %-*s", (int)totals[3], ss);
}
// print group
if (!(flags&FLAG_o)) {
- if (flags&FLAG_n) sprintf(ss = thyme, "%u", (unsigned)st->st_gid);
+ if (flags&FLAG_n) sprintf(ss = tmp, "%u", (unsigned)st->st_gid);
else strwidth(ss = getgroupname(st->st_gid));
printf(" %-*s", (int)totals[4], ss);
}
@@ -439,15 +449,18 @@ static void listfiles(int dirfd, struct dirtree *indir)
if (flags & FLAG_Z)
printf(" %-*s", -(int)totals[7], (char *)sort[next]->extra);
- // print major/minor
+ // print major/minor, or size
if (S_ISCHR(st->st_mode) || S_ISBLK(st->st_mode))
printf("% *d,% 4d", totals[5]-4, major(st->st_rdev),minor(st->st_rdev));
- else printf("% *lld", totals[5]+1, (long long)st->st_size);
+ else if (flags&FLAG_h) {
+ human_readable(tmp, st->st_size, 0);
+ xprintf("%*s", totals[5]+1, tmp);
+ } else printf("% *lld", totals[5]+1, (long long)st->st_size);
// print time, always in --time-style=long-iso
tm = localtime(&(st->st_mtime));
- strftime(thyme, sizeof(thyme), "%F %H:%M", tm);
- xprintf(" %s ", thyme);
+ strftime(tmp, sizeof(tmp), "%F %H:%M", tm);
+ xprintf(" %s ", tmp);
} else if (flags & FLAG_Z)
printf("%-*s ", (int)totals[7], (char *)sort[next]->extra);