Date: Mon, 11 Feb 2002 10:36:46 -0500 (EST) From: Tomas Svensson <tsn@gbdev.net> To: FreeBSD-gnats-submit@freebsd.org Subject: bin/34834: "fix" of du(1) and -h Message-ID: <20020211153646.2C69E4B921@whiterose.net>
next in thread | raw e-mail | index | archive | help
>Number: 34834 >Category: bin >Synopsis: "fix" of du(1) and -h >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: change-request >Submitter-Id: current-users >Arrival-Date: Mon Feb 11 07:40:03 PST 2002 >Closed-Date: >Last-Modified: >Originator: Tomas Svensson >Release: FreeBSD 5.0-CURRENT i386 >Organization: BSD Slackers Inc. >Environment: FreeBSD 5.0-CURRENT i386 >Description: The manpages for df(1), du(1) and ls(1) claim that -h (print human- readable numbers) will reduce the number of digits to three or fewer, but this isn't true. It will print numbers such as 1000K or 1010K (since these are slightly less than a megabyte). Also, the 'K' for kilo should really be 'k'. Here is a fix for du(1) (I'll fix the others too if this patch is accepted). This version will display "1.0M" where the old version displayed "1012K", "32k" instead of "32K" etc. As a "side effect", df doesn't need the math library anymore (still does proper rounding) and the source is more than a kB smaller :) An alternative would be to add a more extensive humanize function to libc... >How-To-Repeat: >Fix: Index: du.c =================================================================== RCS file: /home/ncvs/src/usr.bin/du/du.c,v retrieving revision 1.23 diff -u -r1.23 du.c --- du.c 8 Feb 2002 07:49:13 -0000 1.23 +++ du.c 11 Feb 2002 13:18:33 -0000 @@ -57,39 +57,12 @@ #include <errno.h> #include <fnmatch.h> #include <fts.h> -#include <math.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sysexits.h> #include <unistd.h> -#define KILO_SZ(n) (n) -#define MEGA_SZ(n) ((n) * (n)) -#define GIGA_SZ(n) ((n) * (n) * (n)) -#define TERA_SZ(n) ((n) * (n) * (n) * (n)) -#define PETA_SZ(n) ((n) * (n) * (n) * (n) * (n)) - -#define KILO_2_SZ (KILO_SZ(1024ULL)) -#define MEGA_2_SZ (MEGA_SZ(1024ULL)) -#define GIGA_2_SZ (GIGA_SZ(1024ULL)) -#define TERA_2_SZ (TERA_SZ(1024ULL)) -#define PETA_2_SZ (PETA_SZ(1024ULL)) - -#define KILO_SI_SZ (KILO_SZ(1000ULL)) -#define MEGA_SI_SZ (MEGA_SZ(1000ULL)) -#define GIGA_SI_SZ (GIGA_SZ(1000ULL)) -#define TERA_SI_SZ (TERA_SZ(1000ULL)) -#define PETA_SI_SZ (PETA_SZ(1000ULL)) - -unsigned long long vals_si [] = {1, KILO_SI_SZ, MEGA_SI_SZ, GIGA_SI_SZ, TERA_SI_SZ, PETA_SI_SZ}; -unsigned long long vals_base2[] = {1, KILO_2_SZ, MEGA_2_SZ, GIGA_2_SZ, TERA_2_SZ, PETA_2_SZ}; -unsigned long long *valp; - -typedef enum { NONE, KILO, MEGA, GIGA, TERA, PETA, UNIT_MAX } unit_t; - -int unitp [] = { NONE, KILO, MEGA, GIGA, TERA, PETA }; - SLIST_HEAD(ignhead, ignentry) ignores; struct ignentry { char *mask; @@ -98,8 +71,7 @@ int linkchk __P((FTSENT *)); static void usage __P((void)); -void prthumanval __P((double)); -unit_t unit_adjust __P((double *)); +void prthumanval __P((u_int64_t)); void ignoreadd __P((const char *)); void ignoreclean __P((void)); int ignorep __P((FTSENT *)); @@ -165,7 +137,6 @@ case 'h': putenv("BLOCKSIZE=512"); hflag = 1; - valp = vals_base2; break; case 'k': if (!hflag) @@ -349,43 +320,29 @@ * especially on huge disks. * */ -unit_t -unit_adjust(val) - double *val; -{ - double abval; - unit_t unit; - unsigned int unit_sz; - - abval = fabs(*val); - - unit_sz = abval ? ilogb(abval) / 10 : 0; - - if (unit_sz >= UNIT_MAX) { - unit = NONE; - } else { - unit = unitp[unit_sz]; - *val /= (double)valp[unit_sz]; - } - - return (unit); -} - void prthumanval(bytes) - double bytes; + u_int64_t bytes; { - unit_t unit; + static const char prefixes[] = "BkMGTPE"; + + int i; + u_int64_t s1, s2; - bytes *= 512; - unit = unit_adjust(&bytes); + bytes *= 51200; - if (bytes == 0) - (void)printf(" 0B"); - else if (bytes > 10) - (void)printf("%3.0f%c", bytes, "BKMGTPE"[unit]); - else - (void)printf("%3.1f%c", bytes, "BKMGTPE"[unit]); + for (i = 0; bytes >= 100000 && i < sizeof(prefixes); i++) + bytes /= 1024; + + if (bytes < 1000 ) { + s1 = bytes / 100; + if (( s2 = (( (bytes % 100 ) + 5 ) / 10 ) ) == 10 ) { + s1++; + s2 = 0; + } + printf("%qd.%qd%c", s1, s2, prefixes[i]); + } else + printf("%3qd%c", (bytes + 50) / 100, prefixes[i]); } static void Index: Makefile =================================================================== RCS file: /home/ncvs/src/usr.bin/du/Makefile,v retrieving revision 1.7 diff -u -r1.7 Makefile --- Makefile 8 Feb 2002 22:31:38 -0000 1.7 +++ Makefile 11 Feb 2002 13:18:33 -0000 @@ -2,7 +2,5 @@ # $FreeBSD: src/usr.bin/du/Makefile,v 1.7 2002/02/08 22:31:38 markm Exp $ PROG= du -DPADD= ${LIBM} -LDADD= -lm .include <bsd.prog.mk> >Release-Note: >Audit-Trail: >Unformatted: To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20020211153646.2C69E4B921>