aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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);