[Toybox] [df] percentage different from GNU df

Roy Tam roytam at gmail.com
Fri Nov 9 16:22:30 PST 2012


2012/11/10 Rob Landley <rob at landley.net>:
> On 11/09/2012 12:24:39 AM, Roy Tam wrote:
>>
>> Hello,
>>
>> 2012/11/9 Roy Tam <roytam at gmail.com>:
>> > Hello,
>> >
>> > 2012/11/9 Rob Landley <rob at landley.net>:
>> >> On 10/28/2012 10:50:50 PM, Roy Tam wrote:
>> >>>
>> >>> Hello,
>> >>>
>> >>> I noticed that toybox df shows different percentage from GNU df.
>> >>> GNU df calculates percentage by used/(used+free) while toybox use
>> >>> (blocks-free)/blocks.
>> >>> (which one is better by the way?)
>> >>
>> >>
>> >> According to posix-2008:
>> >>
>> >>> <percentage used>
>> >>>
>> >>> The percentage of the normally available space that is currently
>> >>> allocated
>> >>> to all
>> >>> files on the file system. This shall be calculated using the fraction:
>> >>>   <space used>/( <space used>+ <space free>)
>> >>> expressed as a percentage. This percentage may be greater than 100 if
>> >>> <space free> is
>> >>> less than zero. The percentage value shall be expressed as a positive
>> >>> integer, with
>> >>> any fractional result causing it to be rounded to the next highest
>> >>> integer.
>> >>
>> >>
>> >> The "space used" and "space free" entries are the used/available
>> >> displayed
>> >> in columns 3 and 4. The "any fractional result" implies that you do
>> >> something like:
>> >>
>> >>   pct=(used*100)/(used+free)
>> >>   if (pct*(used+free) != (used*100)) pct++;
>> >>
>> >> (Except all with 64 bit math so overflow sucks less.)
>> >>
>> >>
>> >>> toybox$ ../busybox/busybox df
>> >>> Filesystem           1K-blocks      Used Available Use% Mounted on
>> >>> udev                     10240         0     10240   0% /dev
>> >>> tmpfs                    12456       160     12296   1% /run
>> >>> /dev/disk/by-uuid/4277274d-e9a1-42ff-a247-b75bde522deb
>> >>>                        1913244   1151656    664400  63% /
>> >>> tmpfs                    24912         0     24912   0% /run/shm
>> >>
>> >>
>> >> 160/(160+12296.0)
>> >> 0.012845215157353885
>> >>
>> >> Not doing the pedantic rounding up.
>> >>
>> >>
>> >>> toybox$ df
>> >>> Filesystem           1K-blocks      Used Available Use% Mounted on
>> >>> rootfs                 1913244   1151656    664400  64% /
>> >>> udev                     10240         0     10240   0% /dev
>> >>> tmpfs                    12456       160     12296   2% /run
>> >>> /dev/disk/by-uuid/4277274d-e9a1-42ff-a247-b75bde522deb
>> >>>                        1913244   1151656    664400  64% /
>> >>> tmpfs                    24912         0     24912   0% /run/shm
>> >>
>> >>
>> >> Doing the pedantic rounding up.
>> >>
>> >>
>> >>> toybox$ ./toybox df
>> >>> Filesystem      1K-blocks       Used Available Use% Mounted on
>> >>> tmpfs               24912          0     24912   0% /run/shm
>> >>> /dev/sda1         1913244    1151656    664400  66% /
>> >>> tmpfs               12456        160     12296   2% /run
>> >>> udev                10240          0     10240   0% /dev
>> >>
>> >>
>> >> Showing used as a percentage of 1K-blocks, ignoring "available"
>> >> altogether.
>> >>
>> >> Right, I fixed it to match what the standard requires, which seems to
>> >> be
>> >> what upstream is doing.
>> >>
>> >
>> > I'm now hitting segfault with hg head.
>> >
>> > toybox$ CFLAGS="-O0 -g" make
>> > scripts/make.sh
>> > Make generated/config.h from .config.
>> > Extract configuration information from toys/*.c files...
>> > Generate headers from toys/*/*.c...
>> > generated/newtoys.h
>> > generated/globals.h
>> > generated/help.h
>> > Extract help text from Config.in.
>> > Library probe...
>> > Compile toybox...
>> > toybox$ gdb --args ./toybox_unstripped df
>> > GNU gdb (GDB) 7.4.1-debian
>> > Copyright (C) 2012 Free Software Foundation, Inc.
>> > License GPLv3+: GNU GPL version 3 or later
>> > <http://gnu.org/licenses/gpl.html>
>> > This is free software: you are free to change and redistribute it.
>> > There is NO WARRANTY, to the extent permitted by law.  Type "show
>> > copying"
>> > and "show warranty" for details.
>> > This GDB was configured as "i486-linux-gnu".
>> > For bug reporting instructions, please see:
>> > <http://www.gnu.org/software/gdb/bugs/>...
>> > Reading symbols from /home/roy/toybox/toybox_unstripped...done.
>> > (gdb) r
>> > Starting program: /home/roy/toybox/toybox_unstripped df
>> > Filesystem      1K-blocks       Used Available Use% Mounted on
>> >
>> > Program received signal SIGSEGV, Segmentation fault.
>> > 0xb7e867a4 in vfprintf () from /lib/i386-linux-gnu/i686/cmov/libc.so.6
>> > (gdb) bt
>> > #0  0xb7e867a4 in vfprintf () from
>> > /lib/i386-linux-gnu/i686/cmov/libc.so.6
>> > #1  0xb7e87270 in vprintf () from
>> > /lib/i386-linux-gnu/i686/cmov/libc.so.6
>> > #2  0x0804ce44 in xprintf (format=0x805c445 "%s% *ld % 10ld % 9ld %
>> > 3ld%% %s\n") at lib/lib.c:152
>> > #3  0x08051c78 in show_mt (mt=0x806b8b0) at toys/posix/df.c:94
>> > #4  show_mt (mt=0x806b8b0) at toys/posix/df.c:49
>> > #5  0x08051db6 in df_main () at toys/posix/df.c:159
>> > #6  0x0804b3b2 in toy_exec (argv=0xbffffd78) at main.c:104
>> > #7  0x0804b3ed in toybox_main () at main.c:118
>> > #8  0x0804b3b2 in toy_exec (argv=0xbffffd74) at main.c:104
>> > #9  0x0804b3ed in toybox_main () at main.c:118
>> > #10 0x0804b14a in main (argc=2, argv=0xbffffd74) at main.c:159
>> > (gdb) frame 2
>> > #2  0x0804ce44 in xprintf (format=0x805c445 "%s% *ld % 10ld % 9ld %
>> > 3ld%% %s\n") at lib/lib.c:152
>> > 152             vprintf(format, va);
>> > (gdb) print *va
>> > $1 = 139 '\213'
>> > (gdb) list
>> > 147     void xprintf(char *format, ...)
>> > 148     {
>> > 149             va_list va;
>> > 150             va_start(va, format);
>> > 151
>> > 152             vprintf(format, va);
>> > 153             if (ferror(stdout)) perror_exit("write");
>> > 154     }
>> > 155
>> > 156     void xputs(char *s)
>> > (gdb) print va
>> > $2 = (va_list) 0xbffffae4 "\213\271\006\b\024"
>> > (gdb)
>> >
>>
>> Alright, a quick fix is done:
>> --- df.c        2012-11-09 05:03:03.000000000 +0800
>> +++ df.c_qf     2012-11-09 14:23:15.000000000 +0800
>> @@ -83,20 +83,20 @@
>>
>>         device = *mt->device == '/' ? realpath(mt->device, NULL) : NULL;
>>         if (!device) device = mt->device;
>>
>>         // Figure out appropriate spacing
>>         len = 25 - strlen(device);
>>         if (len < 1) len = 1;
>>         if (CFG_DF_PEDANTIC && (toys.optflags & FLAG_P)) {
>> -               xprintf("%s %ld %ld %ld %ld%% %s\n", device, size, used,
>> avail,
>> +               xprintf("%s %lld %lld %lld %lld%% %s\n", device, size,
>> used, avail,
>>                                 percent, mt->dir);
>>         } else {
>> -               xprintf("%s% *ld % 10ld % 9ld % 3ld%% %s\n", device, len,
>> +               xprintf("%s% *lld % 10lld % 9lld % 3lld%% %s\n", device,
>> len,
>>                         size, used, avail, percent, mt->dir);
>>         }
>>
>>         if (device != mt->device) free(device);
>>  }
>
>
> Oops.
>
> (Worked fine when I built it on my 64 bit netbook. :)
>
> Applied, thanks.

Did you push it?
I can't find it in http://www.landley.net/hg/toybox

>
> Rob



More information about the Toybox mailing list