aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Landley <rob@landley.net>2019-04-04 14:15:37 -0500
committerRob Landley <rob@landley.net>2019-04-04 14:15:37 -0500
commit170ce208408f72d2c679eb165ce2c2c1d2619cd9 (patch)
tree7f001e3c2922f4030778636f368ffa34aaa64b49
parent063e8a8deaa89ca35ce6795f216c870e2df0743d (diff)
downloadtoybox-170ce208408f72d2c679eb165ce2c2c1d2619cd9.tar.gz
Tweak stat.
next_printf() shouldn't return null unless it never found the start of an escape sequence (it'll return a pointer to the null at the end of the string otherwise), and the only time we point it at a % and it doesn't is when it's %%. So handle that before calling. (Also, a single trailing % prints in other implementations, and while I'm there update to use FLAG() macros, add a couple comments, and only xflush() once per pattern.)
-rw-r--r--toys/other/stat.c30
1 files changed, 16 insertions, 14 deletions
diff --git a/toys/other/stat.c b/toys/other/stat.c
index 22b1b833..3f1d1765 100644
--- a/toys/other/stat.c
+++ b/toys/other/stat.c
@@ -108,10 +108,10 @@ static void print_stat(char type)
}
llist_traverse(mt, free);
} else if (type == 'N') {
- xprintf("%s", TT.file);
+ printf("%s", TT.file);
if (S_ISLNK(stat->st_mode))
if (readlink0(TT.file, toybuf, sizeof(toybuf)))
- xprintf(" -> `%s'", toybuf);
+ printf(" -> `%s'", toybuf);
} else if (type == 'o') out('u', stat->st_blksize);
else if (type == 's') out('u', stat->st_size);
else if (type == 't') out('x', dev_major(stat->st_rdev));
@@ -124,7 +124,7 @@ static void print_stat(char type)
else if (type == 'Y') out('u', stat->st_mtime);
else if (type == 'z') date_stat_format(&stat->st_ctim);
else if (type == 'Z') out('u', stat->st_ctime);
- else xprintf("?");
+ else putchar('?');
}
static void print_statfs(char type) {
@@ -166,13 +166,13 @@ static void print_statfs(char type) {
void stat_main(void)
{
- int flagf = toys.optflags & FLAG_f, i;
+ int flagf = FLAG(f), i;
char *format, *f;
- if (toys.optflags&FLAG_t) {
- format = flagf ? "%n %i %l %t %s %S %b %f %a %c %d" :
- "%n %s %b %f %u %g %D %i %h %t %T %X %Y %Z %o";
- } else format = flagf
+ if (FLAG(t)) format = flagf
+ ? "%n %i %l %t %s %S %b %f %a %c %d"
+ : "%n %s %b %f %u %g %D %i %h %t %T %X %Y %Z %o";
+ else format = flagf
? " File: \"%n\"\n ID: %i Namelen: %l Type: %T\n"
"Block Size: %s Fundamental block size: %S\n"
"Blocks: Total: %b\tFree: %f\tAvailable: %a\n"
@@ -182,25 +182,27 @@ void stat_main(void)
"Access: (0%a/%A)\tUid: (%5u/%8U)\tGid: (%5g/%8G)\n"
"Access: %x\nModify: %y\nChange: %z";
- if (toys.optflags & FLAG_c) format = TT.c;
+ if (FLAG(c)) format = TT.c;
+ // loop through files listed on command line
for (i = 0; toys.optargs[i]; i++) {
- int L = toys.optflags & FLAG_L;
+ // stat the file or filesystem
TT.file = toys.optargs[i];
if (flagf && !statfs(TT.file, (void *)&TT.stat));
- else if (flagf || (L ? stat : lstat)(TT.file, (void *)&TT.stat)) {
+ else if (flagf || (FLAG(L) ? stat : lstat)(TT.file, (void *)&TT.stat)) {
perror_msg("'%s'", TT.file);
continue;
}
+ // parse format and print what it says
for (f = format; *f; f++) {
- if (*f != '%') putchar(*f);
+ if (*f != '%' || !f[1]) putchar(*f);
+ else if (f[1]=='%') putchar(*f++);
else {
f = next_printf(f, &TT.pattern);
- if (!f) error_exit("bad -c \"%s\"", format);
TT.patlen = f-TT.pattern;
- if (TT.patlen>99) error_exit("bad %s", TT.pattern);
+ if (!*f || TT.patlen>99) error_exit("bad %s", TT.pattern);
if (*f == 'n') strout(TT.file);
else if (flagf) print_statfs(*f);
else print_stat(*f);