diff options
author | Elliott Hughes <enh@google.com> | 2015-09-05 05:09:22 -0500 |
---|---|---|
committer | Rob Landley <rob@landley.net> | 2015-09-05 05:09:22 -0500 |
commit | 091997e4c6f5655876a3133ae80b52c2d91a8216 (patch) | |
tree | c7c22a5e6f012c318e182b0ce884540b197393f9 | |
parent | c82343fe0bb293d3ed60b9122426f0bbcb0e58b0 (diff) | |
download | toybox-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.c | 45 |
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); |