In xgetmountlist(), keep track of whether we could stat or not, so we can distinguish an actual device 0:0 from a failed stat/statvfs.
Also switch to FLAG() and capitalize POSIX. --- lib/lib.h | 1 + lib/portability.c | 12 ++++------- toys/posix/df.c | 55 ++++++++++++++++++++++++++++------------------- 3 files changed, 38 insertions(+), 30 deletions(-)
From f931aa2af384be7a041bd6ce14ec4bb2b1ce89bf Mon Sep 17 00:00:00 2001 From: Elliott Hughes <[email protected]> Date: Fri, 12 Feb 2021 17:19:48 -0800 Subject: [PATCH] df: -a should even show mounts we couldn't stat. In xgetmountlist(), keep track of whether we could stat or not, so we can distinguish an actual device 0:0 from a failed stat/statvfs. Also switch to FLAG() and capitalize POSIX. --- lib/lib.h | 1 + lib/portability.c | 12 ++++------- toys/posix/df.c | 55 ++++++++++++++++++++++++++++------------------- 3 files changed, 38 insertions(+), 30 deletions(-) diff --git a/lib/lib.h b/lib/lib.h index f9c04281..8b58baad 100644 --- a/lib/lib.h +++ b/lib/lib.h @@ -390,6 +390,7 @@ struct mtab_list { struct mtab_list *next, *prev; struct stat stat; struct statvfs statvfs; + int stat_failed; char *dir; char *device; char *opts; diff --git a/lib/portability.c b/lib/portability.c index 0c364c29..3dd78170 100644 --- a/lib/portability.c +++ b/lib/portability.c @@ -75,8 +75,8 @@ struct mtab_list *xgetmountlist(char *path) // Collect details about mounted filesystem. // Don't report errors, just leave data zeroed. - stat(me->f_mntonname, &(mt->stat)); - statvfs(me->f_mntonname, &(mt->statvfs)); + if (stat(me->f_mntonname, &(mt->stat))) mt->stat_failed++; + if (statvfs(me->f_mntonname, &(mt->statvfs))) mt->stat_failed++; // Remember information from struct statfs. mt->dir = stpcpy(mt->type, me->f_fstypename)+1; @@ -156,10 +156,6 @@ struct mtab_list *xgetmountlist(char *path) if (!(fp = setmntent(p, "r"))) perror_exit("bad %s", p); - // The "test" part of the loop is done before the first time through and - // again after each "increment", so putting the actual load there avoids - // duplicating it. If the load was NULL, the loop stops. - while ((me = getmntent(fp))) { mt = xzalloc(sizeof(struct mtab_list) + strlen(me->mnt_fsname) + strlen(me->mnt_dir) + strlen(me->mnt_type) + strlen(me->mnt_opts) + 4); @@ -168,8 +164,8 @@ struct mtab_list *xgetmountlist(char *path) // Collect details about mounted filesystem // Don't report errors, just leave data zeroed if (!path) { - stat(me->mnt_dir, &(mt->stat)); - statvfs(me->mnt_dir, &(mt->statvfs)); + if (stat(me->mnt_dir, &(mt->stat))) mt->stat_failed++; + if (statvfs(me->mnt_dir, &(mt->statvfs))) mt->stat_failed++; } // Remember information from /proc/mounts diff --git a/toys/posix/df.c b/toys/posix/df.c index 53d99f56..6005657e 100644 --- a/toys/posix/df.c +++ b/toys/posix/df.c @@ -24,7 +24,7 @@ config DF -i Show inodes instead of blocks -t type Display only filesystems of this type - Pedantic provides a slightly less useful output format dictated by Posix, + Pedantic provides a slightly less useful output format dictated by POSIX, and sets the units to 512 bytes instead of the default 1024 bytes. */ @@ -59,15 +59,15 @@ static void show_header() // The filesystem column is always at least this wide. if (TT.column_widths[0] < 14) TT.column_widths[0] = 14; - if ((toys.optflags & (FLAG_H|FLAG_h))) { - xprintf((toys.optflags&FLAG_i) ? + if (FLAG(H) || FLAG(h)) { + xprintf(FLAG(i) ? "%-*sInodes IUsed IFree IUse%% Mounted on\n" : "%-*s Size Used Avail Use%% Mounted on\n", TT.column_widths[0], "Filesystem"); } else { const char *item_label, *used_label, *free_label, *use_label; - if (toys.optflags & FLAG_i) { + if (FLAG(i)) { item_label = "Inodes"; used_label = "IUsed"; free_label = "IFree"; @@ -76,7 +76,7 @@ static void show_header() item_label = TT.units == 512 ? "512-blocks" : "1K-blocks"; used_label = "Used"; free_label = "Available"; - use_label = toys.optflags & FLAG_P ? "Capacity" : "Use%"; + use_label = FLAG(P) ? "Capacity" : "Use%"; } measure_column(1, item_label); @@ -114,11 +114,11 @@ static void show_mt(struct mtab_list *mt, int measuring) } // If we don't have -a, skip synthetic filesystems - if (!(toys.optflags & FLAG_a) && !mt->statvfs.f_blocks) return; + if (!FLAG(a) && !mt->statvfs.f_blocks) return; // Figure out how much total/used/free space this filesystem has, // forcing 64-bit math because filesystems are big now. - if (toys.optflags & FLAG_i) { + if (FLAG(i)) { size = mt->statvfs.f_files; used = mt->statvfs.f_files - mt->statvfs.f_ffree; avail = getuid() ? mt->statvfs.f_favail : mt->statvfs.f_ffree; @@ -145,17 +145,27 @@ static void show_mt(struct mtab_list *mt, int measuring) } else { if (!TT.header_shown) show_header(); - if (toys.optflags & (FLAG_H|FLAG_h)) { - char *size_str = toybuf, *used_str = toybuf+64, *avail_str = toybuf+128; - int hr_flags = (toys.optflags & FLAG_H) ? HR_1000 : 0; - int w = 4 + !!(toys.optflags & FLAG_i); - - human_readable(size_str, size, hr_flags); - human_readable(used_str, used, hr_flags); - human_readable(avail_str, avail, hr_flags); - xprintf("%-*s %*s %*s %*s %*llu%% %s\n", + if (FLAG(H) || FLAG(h)) { + char *size_str = toybuf, *used_str = toybuf+64, *avail_str = toybuf+128, + *pc_str = toybuf+192; + int hr_flags = FLAG(H) ? HR_1000 : 0; + int w = 4 + !!FLAG(i); + + if (mt->stat_failed) { + size_str = used_str = avail_str = pc_str = "-"; + } else { + human_readable(size_str, size, hr_flags); + human_readable(used_str, used, hr_flags); + human_readable(avail_str, avail, hr_flags); + sprintf(pc_str, "%llu%%", percent); + } + xprintf("%-*s %*s %*s %*s %*s %s\n", TT.column_widths[0], device, - w, size_str, w, used_str, w, avail_str, w-1, percent, mt->dir); + w, size_str, w, used_str, w, avail_str, w-1, pc_str, mt->dir); + } else if (mt->stat_failed) { + xprintf("%-*s %*s %*s %*s %*s %s\n", TT.column_widths[0], "-", + TT.column_widths[1], "-", TT.column_widths[2], "-", + TT.column_widths[3], "-", TT.column_widths[4], "-", mt->dir); } else xprintf("%-*s %*llu %*llu %*llu %*llu%% %s\n", TT.column_widths[0], device, TT.column_widths[1], size, @@ -173,11 +183,11 @@ void df_main(void) struct mtab_list *mt, *mtstart, *mtend; int measuring; - if (toys.optflags & (FLAG_H|FLAG_h)) { + if (FLAG(H) || FLAG(h)) { TT.units = 1; } else { // Units are 512 bytes if you select "pedantic" without "kilobytes". - TT.units = toys.optflags & FLAG_P ? 512 : 1024; + TT.units = FLAG(P) ? 512 : 1024; } if (!(mtstart = xgetmountlist(0))) return; @@ -216,7 +226,7 @@ void df_main(void) struct mtab_list *mt2, *mt3; // 0:0 is LANANA null device - if (!mt->stat.st_dev) continue; + if (!mt->stat.st_dev && !mt->stat_failed) continue; // Filter out overmounts. mt3 = mt; @@ -224,7 +234,7 @@ void df_main(void) if (mt->stat.st_dev == mt2->stat.st_dev) { // For --bind mounts, show earliest mount if (!strcmp(mt->device, mt2->device)) { - if (!(toys.optflags & FLAG_a)) mt3->stat.st_dev = 0; + if (!FLAG(a)) mt3->stat.st_dev = 0; mt3 = mt2; } else mt2->stat.st_dev = 0; } @@ -235,7 +245,8 @@ void df_main(void) for (measuring = 1; measuring >= 0; --measuring) { // Cosmetic: show filesystems in creation order. for (mt = mtstart; mt; mt = mt->next) { - if (mt->stat.st_dev) show_mt(mt, measuring); + if (mt->stat_failed || mt->stat.st_dev) + show_mt(mt, measuring); } } } -- 2.30.0.478.g8a0d178c01-goog
_______________________________________________ Toybox mailing list [email protected] http://lists.landley.net/listinfo.cgi/toybox-landley.net
