]> granicus.if.org Git - procps-ng/commitdiff
free: Use IEC units
authorCraig Small <csmall@enc.com.au>
Fri, 3 Apr 2015 08:18:58 +0000 (19:18 +1100)
committerCraig Small <csmall@enc.com.au>
Fri, 3 Apr 2015 08:18:58 +0000 (19:18 +1100)
Free always used 1024 based units but used the confusing old style
kilo,mega etc.

This change changes the names to kibi,mebi for 1024 based divisors
and kilo,mega for 1000 based divisors or IEC units.

It also checks if you try to set two units, e.g free -k -m
Petabyte and Pebibyte have been added.

If you used to use the long options such as --mega these will now
actually print megabytes (they previously printed mebibytes).
The short options are being used on the IEC units

References: https://www.gitorious.org/procps/procps/merge_requests/38

Signed-off-by: Craig Small <csmall@enc.com.au>
free.1
free.c
testsuite/free.test/free.exp

diff --git a/free.1 b/free.1
index 20407f920cde5b129937056eb5e4e124727c2228..4093048b880491d9ab975bed8da750474737f772 100644 (file)
--- a/free.1
+++ b/free.1
@@ -2,7 +2,7 @@
 .\"  This page Copyright (C) 1993 Matt Welsh, mdw@sunsite.unc.edu.
 .\"  Long options where added at April 15th, 2011.
 .\"  Freely distributable under the terms of the GPL
-.TH FREE 1 "July 2014" "procps-ng" "User Commands"
+.TH FREE 1 "Apr 2015" "procps-ng" "User Commands"
 .SH NAME
 free \- Display amount of free and used memory in the system
 .SH SYNOPSIS
@@ -50,17 +50,35 @@ kernels 3.14, emulated on kernels 2.6.27+, otherwise the same as \fBfree\fR)
 \fB\-b\fR, \fB\-\-bytes\fR
 Display the amount of memory in bytes.
 .TP
-\fB\-k\fR, \fB\-\-kilo\fR
-Display the amount of memory in kilobytes.  This is the default.
+\fB\-k\fR, \fB\-\-kibi\fR
+Display the amount of memory in kibibytes.  This is the default.
 .TP
-\fB\-m\fR, \fB\-\-mega\fR
-Display the amount of memory in megabytes.
+\fB\-m\fR, \fB\-\-mebi\fR
+Display the amount of memory in mebibytes.
 .TP
-\fB\-g\fR, \fB\-\-giga\fR
-Display the amount of memory in gigabytes.
+\fB\-g\fR, \fB\-\-gibi\fR
+Display the amount of memory in gibibytes.
+.TP
+\fB\-\-tebi\fR
+Display the amount of memory in tebibytes.
+.TP
+\fB\-\-pebi\fR
+Display the amount of memory in pebibytes.
+.TP
+\fB\-\-kilo\fR
+Display the amount of memory in kilobytes. Implies --si.
+.TP
+\fB\-\-mega\fR
+Display the amount of memory in megabytes. Implies --si.
+.TP
+\fB\-\-giga\fR
+Display the amount of memory in gigabytes. Implies --si.
 .TP
 \fB\-\-tera\fR
-Display the amount of memory in terabytes.
+Display the amount of memory in terabytes. Implies --si.
+.TP
+\fB\-\-peta\fR
+Display the amount of memory in petabytes. Implies --si.
 .TP
 \fB\-h\fR, \fB\-\-human\fP
 Show all output fields automatically scaled to shortest three digit unit and
@@ -68,14 +86,15 @@ display the units of print out.  Following units are used.
 .sp
 .nf
   B = bytes
-  K = kilos
-  M = megas
-  G = gigas
-  T = teras
+  K = kibibyte
+  M = mebibyte
+  G = gibibyte
+  T = tebibyte
+  P = pebibyte
 .fi
 .sp
-If unit is missing, and you have petabyte of RAM or swap, the number is in
-terabytes and columns might not be aligned with header.
+If unit is missing, and you have exbibyte of RAM or swap, the number is in
+tebibytes and columns might not be aligned with header.
 .TP
 \fB\-w\fR, \fB\-\-wide\fR
 Switch to the wide mode. The wide mode produces lines longer
@@ -101,7 +120,8 @@ apart.  You may actually specify any floating point number for
 is used for microsecond resolution delay times.
 .TP
 \fB\-\-si\fR
-Use power of 1000 not 1024.
+Use kilo, mega, giga etc (power of 1000) instead of kibi, mebi, gibi (power 
+of 1024).
 .TP
 \fB\-t\fR, \fB\-\-total\fR
 Display a line showing the column totals.
diff --git a/free.c b/free.c
index 09e7654a2bf9ec418d289eaca7391b5b7b2610fa..b19e07ff8112d9d7c591ce8305c79f69c7a4da6a 100644 (file)
--- a/free.c
+++ b/free.c
@@ -74,10 +74,16 @@ static void __attribute__ ((__noreturn__))
              _(" %s [options]\n"), program_invocation_short_name);
        fputs(USAGE_OPTIONS, out);
        fputs(_(" -b, --bytes         show output in bytes\n"), out);
-       fputs(_(" -k, --kilo          show output in kilobytes\n"), out);
-       fputs(_(" -m, --mega          show output in megabytes\n"), out);
-       fputs(_(" -g, --giga          show output in gigabytes\n"), out);
+       fputs(_("     --kilo          show output in kilobytes\n"), out);
+       fputs(_("     --mega          show output in megabytes\n"), out);
+       fputs(_("     --giga          show output in gigabytes\n"), out);
        fputs(_("     --tera          show output in terabytes\n"), out);
+       fputs(_("     --peta          show output in petabytes\n"), out);
+       fputs(_(" -k, --kibi          show output in kibibytes\n"), out);
+       fputs(_(" -m, --mebi          show output in mebibytes\n"), out);
+       fputs(_(" -g, --gibi          show output in gibibytes\n"), out);
+       fputs(_("     --tebi          show output in tebibytes\n"), out);
+       fputs(_("     --pebi          show output in pebibytes\n"), out);
        fputs(_(" -h, --human         show human-readable output\n"), out);
        fputs(_("     --si            use powers of 1000 not 1024\n"), out);
        fputs(_(" -l, --lohi          show detailed low and high memory statistics\n"), out);
@@ -101,7 +107,7 @@ double power(unsigned int base, unsigned int expo)
 /* idea of this function is copied from top size scaling */
 static const char *scale_size(unsigned long size, int flags, struct commandline_arguments args)
 {
-       static char nextup[] = { 'B', 'K', 'M', 'G', 'T', 0 };
+       static char nextup[] = { 'B', 'K', 'M', 'G', 'T', 'P', 0 };
        static char buf[BUFSIZ];
        int i;
        char *up;
@@ -163,6 +169,7 @@ static const char *scale_size(unsigned long size, int flags, struct commandline_
                case 3:
                case 4:
                case 5:
+               case 6:
                        if (4 >=
                            snprintf(buf, sizeof(buf), "%.1f%c",
                                     (float)(size / power(base, i - 2)), *up))
@@ -172,21 +179,29 @@ static const char *scale_size(unsigned long size, int flags, struct commandline_
                                     (long)(size / power(base, i - 2)), *up))
                                return buf;
                        break;
-               case 6:
+               case 7:
                        break;
                }
        }
        /*
-        * On system where there is more than petabyte of memory or swap the
+        * On system where there is more than exbibyte of memory or swap the
         * output does not fit to column. For incoming few years this should
-        * not be a big problem (wrote at Apr, 2011).
+        * not be a big problem (wrote at Apr, 2015).
         */
        return buf;
 }
 
+static void check_unit_set(int *unit_set)
+{
+    if (*unit_set)
+       xerrx(EXIT_FAILURE,
+               _("Multiple unit options doesn't make sense."));
+    *unit_set = 1;
+}
+
 int main(int argc, char **argv)
 {
-       int c, flags = 0;
+       int c, flags = 0, unit_set = 0;
        char *endptr;
        struct commandline_arguments args;
 
@@ -196,16 +211,28 @@ int main(int argc, char **argv)
         */
        enum {
                SI_OPTION = CHAR_MAX + 1,
+               KILO_OPTION,
+               MEGA_OPTION,
+               GIGA_OPTION,
                TERA_OPTION,
+               PETA_OPTION,
+               TEBI_OPTION,
+               PEBI_OPTION,
                HELP_OPTION
        };
 
        static const struct option longopts[] = {
                {  "bytes",     no_argument,        NULL,  'b'          },
-               {  "kilo",      no_argument,        NULL,  'k'          },
-               {  "mega",      no_argument,        NULL,  'm'          },
-               {  "giga",      no_argument,        NULL,  'g'          },
+               {  "kilo",      no_argument,        NULL,  KILO_OPTION  },
+               {  "mega",      no_argument,        NULL,  MEGA_OPTION  },
+               {  "giga",      no_argument,        NULL,  GIGA_OPTION  },
                {  "tera",      no_argument,        NULL,  TERA_OPTION  },
+               {  "peta",      no_argument,        NULL,  PETA_OPTION  },
+               {  "kibi",      no_argument,        NULL,  'k'          },
+               {  "mebi",      no_argument,        NULL,  'm'          },
+               {  "gibi",      no_argument,        NULL,  'g'          },
+               {  "tebi",      no_argument,        NULL,  TEBI_OPTION  },
+               {  "pebi",      no_argument,        NULL,  PEBI_OPTION  },
                {  "human",     no_argument,        NULL,  'h'          },
                {  "si",        no_argument,        NULL,  SI_OPTION    },
                {  "lohi",      no_argument,        NULL,  'l'          },
@@ -234,19 +261,53 @@ int main(int argc, char **argv)
        while ((c = getopt_long(argc, argv, "bkmghltc:ws:V", longopts, NULL)) != -1)
                switch (c) {
                case 'b':
+                       check_unit_set(&unit_set);
                        args.exponent = 1;
                        break;
                case 'k':
+                       check_unit_set(&unit_set);
                        args.exponent = 2;
                        break;
                case 'm':
+                       check_unit_set(&unit_set);
                        args.exponent = 3;
                        break;
                case 'g':
+                       check_unit_set(&unit_set);
+                       args.exponent = 4;
+                       break;
+               case TEBI_OPTION:
+                       check_unit_set(&unit_set);
+                       args.exponent = 5;
+                       break;
+               case PEBI_OPTION:
+                       check_unit_set(&unit_set);
+                       args.exponent = 6;
+                       break;
+               case KILO_OPTION:
+                       check_unit_set(&unit_set);
+                       args.exponent = 2;
+                       flags |= FREE_SI;
+                       break;
+               case MEGA_OPTION:
+                       check_unit_set(&unit_set);
+                       args.exponent = 3;
+                       flags |= FREE_SI;
+                       break;
+               case GIGA_OPTION:
+                       check_unit_set(&unit_set);
                        args.exponent = 4;
+                       flags |= FREE_SI;
                        break;
                case TERA_OPTION:
+                       check_unit_set(&unit_set);
                        args.exponent = 5;
+                       flags |= FREE_SI;
+                       break;
+               case PETA_OPTION:
+                       check_unit_set(&unit_set);
+                       args.exponent = 6;
+                       flags |= FREE_SI;
                        break;
                case 'h':
                        flags |= FREE_HUMANREADABLE;
index b312a6de2872103df47883b580c4d85b4f8b963b..83e197e4295febc81d71ba28e92186063ac153dd 100644 (file)
@@ -19,7 +19,7 @@ set swaptotal [ expr { $swaptotal_kb * 1024 } ]
 spawn $free -b
 expect_pass "$test" "^${free_header}Mem:\\s+${memtotal}\\s+\\d+\\s+\\d+\\s+\\d+\\s+\\d+\\s+\\d+\\s*Swap:\\s+${swaptotal}\\s+\\d+\\s+\\d+\\s*"
 
-foreach {arg divisor } {-k 1 -m 1024 -g 1048576 } {
+foreach {arg divisor } {-k 1 -m 1024 -g 1048576 --mega 1000 --giga 1000000 } {
     set test "free with $arg argument"
     set memtotal [ expr { $memtotal_kb / $divisor } ]
     set swaptotal [ expr { $swaptotal_kb / $divisor } ]