1
0
mirror of git://git.sv.gnu.org/coreutils.git synced 2026-04-12 06:57:33 +02:00

(<inttypes.h>): Include if HAVE_INTTYPES_H.

("human.h"): Include.
(LONGEST_HUMAN_READABLE_1K_BYTE_BLOCKS): Remove.
(human_readable_base): Renamed from human_blocks; value is now
zero or positive integer, not just zero or nonzero.
(output_units): New variable;
replaces booleans kilobyte_blocks and megabyte_blocks.
(long_options): Add --si or -H.
(print_header): Adjust to renamed option variables.
(human_readable_1k_blocks): Remove.
(show_dev): Count blocks using uintmax_t, not long.
Calculate percentages using double, not long; this still isn't
perfect as it suffers double rounding, but it's more likely to
round correctly in practice than using long did.
Adjust to renamed option variables.
Use new human_readable library function to format uintmax_t values.
(usage): Add -H, --si.
(main): Adjust to renamed option variables.
Use -H if BLOCKSIZE is SI.  Add -H.
This commit is contained in:
Jim Meyering
1997-11-30 10:25:02 +00:00
parent 72bc3b818f
commit 76916942ca

186
src/df.c
View File

@@ -16,9 +16,13 @@
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
/* Written by David MacKenzie <djm@gnu.ai.mit.edu>.
--human-readable and --megabyte options added by lm@sgi.com. */
--human-readable and --megabyte options added by lm@sgi.com.
--si and large file support added by eggert@twinsun.com. */
#include <config.h>
#if HAVE_INTTYPES_H
# include <inttypes.h>
#endif
#include <stdio.h>
#include <sys/types.h>
#include <getopt.h>
@@ -29,18 +33,13 @@
#include "system.h"
#include "save-cwd.h"
#include "error.h"
#include "human.h"
char *dirname ();
void strip_trailing_slashes ();
char *xstrdup ();
char *xgetcwd ();
/* The maximum length of a human-readable string. Be pessimistic
and assume `int' is 64-bits wide. Converting 2^63 - 1 gives the
14-character string, 8796093022208G. The number being converted
is the number of 1024-byte blocks, so we divide by 1024 * 1024. */
#define LONGEST_HUMAN_READABLE_1K_BYTE_BLOCKS 14
/* Name this program was run with. */
char *program_name;
@@ -55,14 +54,11 @@ static int show_all_fs;
command line argument -- even if it's a dummy (automounter) entry. */
static int show_listed_fs;
/* If nonzero, use variable sized printouts instead of 512-byte blocks. */
static int human_blocks;
/* base used for human style output */
static int human_readable_base;
/* If nonzero, use 1K blocks instead of 512-byte blocks. */
static int kilobyte_blocks;
/* If nonzero, use 1M blocks instead of 512-byte blocks. */
static int megabyte_blocks;
/* The units to count in. */
static int output_units;
/* If nonzero, use the POSIX output format. */
static int posix_format;
@@ -119,6 +115,7 @@ static struct option const long_options[] =
{"all", no_argument, &show_all_fs, 1},
{"inodes", no_argument, &inode_format, 1},
{"human-readable", no_argument, 0, 'h'},
{"si", no_argument, 0, 'H'},
{"kilobytes", no_argument, 0, 'k'},
{"megabytes", no_argument, 0, 'm'},
{"portability", no_argument, &posix_format, 1},
@@ -145,66 +142,16 @@ print_header (void)
if (inode_format)
printf (" Inodes IUsed IFree %%IUsed");
else
if (megabyte_blocks)
if (output_units == 1024 * 1024)
printf (" MB-blocks Used Available Capacity");
else if (human_blocks)
else if (human_readable_base)
printf (" Size Used Avail Capacity");
else
printf (" %s Used Available Capacity",
kilobyte_blocks ? "1024-blocks" : " 512-blocks");
output_units == 1024 ? "1024-blocks" : " 512-blocks");
printf (" Mounted on\n");
}
/* Convert N_1K_BYTE_BLOCKS to a more readable string than %d would.
Most people visually process strings of 3-4 digits effectively,
but longer strings of digits are more prone to misinterpretation.
Hence, converting to an abbreviated form usually improves readability.
Use a suffix indicating multiples of 1024 (M) and 1024*1024 (G).
For example, 8500 would be converted to 8.3M, 133456345 to 127G,
and so on. Numbers smaller than 1024 get the `K' suffix. */
static char *
human_readable_1k_blocks (int n_1k_byte_blocks, char *buf, int buf_len)
{
const char *suffix;
double amt;
char *p;
assert (buf_len > LONGEST_HUMAN_READABLE_1K_BYTE_BLOCKS);
p = buf;
amt = n_1k_byte_blocks;
if (amt >= 1024 * 1024)
{
amt /= (1024 * 1024);
suffix = "G";
}
else if (amt >= 1024)
{
amt /= 1024;
suffix = "M";
}
else
{
suffix = "K";
}
if (amt >= 10)
{
sprintf (p, "%4.0f%s", amt, suffix);
}
else if (amt == 0)
{
strcpy (p, "0");
}
else
{
sprintf (p, "%4.1f%s", amt, suffix);
}
return (p);
}
/* If FSTYPE is a type of filesystem that should be listed,
return nonzero, else zero. */
@@ -248,10 +195,10 @@ static void
show_dev (const char *disk, const char *mount_point, const char *fstype)
{
struct fs_usage fsu;
long blocks_used;
long blocks_percent_used;
long inodes_used;
long inodes_percent_used;
uintmax_t blocks_used;
double blocks_percent_used;
uintmax_t inodes_used;
double inodes_percent_used;
const char *stat_file;
if (!selected_fstype (fstype) || excluded_fstype (fstype))
@@ -270,19 +217,6 @@ show_dev (const char *disk, const char *mount_point, const char *fstype)
return;
}
if (megabyte_blocks)
{
fsu.fsu_blocks /= 2*1024;
fsu.fsu_bfree /= 2*1024;
fsu.fsu_bavail /= 2*1024;
}
else if (kilobyte_blocks)
{
fsu.fsu_blocks /= 2;
fsu.fsu_bfree /= 2;
fsu.fsu_bavail /= 2;
}
if (fsu.fsu_blocks == 0)
{
if (!show_all_fs && !show_listed_fs)
@@ -292,8 +226,8 @@ show_dev (const char *disk, const char *mount_point, const char *fstype)
else
{
blocks_used = fsu.fsu_blocks - fsu.fsu_bfree;
blocks_percent_used = (long)
(blocks_used * 100.0 / (blocks_used + fsu.fsu_bavail) + 0.5);
blocks_percent_used =
blocks_used * 100.0 / (blocks_used + fsu.fsu_bavail);
}
if (fsu.fsu_files == 0)
@@ -303,8 +237,7 @@ show_dev (const char *disk, const char *mount_point, const char *fstype)
else
{
inodes_used = fsu.fsu_files - fsu.fsu_ffree;
inodes_percent_used = (long)
(inodes_used * 100.0 / fsu.fsu_files + 0.5);
inodes_percent_used = inodes_used * 100.0 / fsu.fsu_files;
}
if (! disk)
@@ -320,23 +253,27 @@ show_dev (const char *disk, const char *mount_point, const char *fstype)
printf (" %-5s ", fstype);
if (inode_format)
printf (" %7ld %7ld %7ld %5ld%%",
fsu.fsu_files, inodes_used, fsu.fsu_ffree, inodes_percent_used);
else if (human_blocks)
{
char buf[3][LONGEST_HUMAN_READABLE_1K_BYTE_BLOCKS + 1];
printf (" %4s %4s %5s %5ld%% ",
human_readable_1k_blocks (fsu.fsu_blocks, buf[0],
LONGEST_HUMAN_READABLE_1K_BYTE_BLOCKS + 1),
human_readable_1k_blocks (blocks_used, buf[1],
LONGEST_HUMAN_READABLE_1K_BYTE_BLOCKS + 1),
human_readable_1k_blocks (fsu.fsu_bavail, buf[2],
LONGEST_HUMAN_READABLE_1K_BYTE_BLOCKS + 1),
blocks_percent_used);
char buf[3][LONGEST_HUMAN_READABLE + 1];
printf (" %7s %7s %7s %5.0f%%",
human_readable (fsu.fsu_files, buf[0], 1, 1, 0),
human_readable (inodes_used, buf[1], 1, 1, 0),
human_readable (fsu.fsu_ffree, buf[2], 1, 1, 0),
inodes_percent_used);
}
else
printf (" %7ld %7ld %7ld %5ld%% ",
fsu.fsu_blocks, blocks_used, fsu.fsu_bavail, blocks_percent_used);
{
int w = human_readable_base ? 5 : 7;
char buf[3][LONGEST_HUMAN_READABLE + 1];
printf (" %*s %*s %*s %5.0f%% ",
w, human_readable (fsu.fsu_blocks, buf[0], fsu.fsu_blocksize,
output_units, human_readable_base),
w, human_readable (blocks_used, buf[1], fsu.fsu_blocksize,
output_units, human_readable_base),
w, human_readable (fsu.fsu_bavail, buf[2], fsu.fsu_blocksize,
output_units, human_readable_base),
blocks_percent_used);
}
if (mount_point)
{
@@ -559,9 +496,10 @@ or all filesystems by default.\n\
\n\
-a, --all include filesystems having 0 blocks\n\
-h, --human-readable print sizes in human readable format (e.g., 1K 234M 2G)\n\
-H, --si likewise, but use powers of 1000 not 1024\n\
-i, --inodes list inode information instead of block usage\n\
-k, --kilobytes use 1024-byte blocks, not 512 despite POSIXLY_CORRECT\n\
-m, --megabytes use 1024K-byte blocks, not 512 despite POSIXLY_CORRECT\n\
-k, --kilobytes use 1024-byte blocks\n\
-m, --megabytes use 1048576-byte blocks\n\
--no-sync do not invoke sync before getting usage info (default)\n\
-P, --portability use the POSIX output format\n\
--sync invoke sync before getting usage info\n\
@@ -595,21 +533,30 @@ main (int argc, char **argv)
show_listed_fs = 0;
if (getenv ("POSIXLY_CORRECT"))
kilobyte_blocks = 0;
output_units = 512;
else
{
char *bs;
kilobyte_blocks = 1;
if ((bs = getenv ("BLOCKSIZE"))
&& strncmp (bs, "HUMAN", sizeof ("HUMAN") - 1) == 0)
human_blocks = 1;
{
human_readable_base = 1024;
output_units = 1;
}
else if (bs && strcmp (bs, "SI") == 0)
{
human_readable_base = 1000;
output_units = 1;
}
else
output_units = 1024;
}
print_type = 0;
posix_format = 0;
exit_status = 0;
while ((c = getopt_long (argc, argv, "aiF:hkmPTt:vx:", long_options, NULL))
while ((c = getopt_long (argc, argv, "aiF:hHkmPTt:vx:", long_options, NULL))
!= -1)
{
switch (c)
@@ -623,19 +570,20 @@ main (int argc, char **argv)
inode_format = 1;
break;
case 'h':
human_blocks = 1;
kilobyte_blocks = 1;
megabyte_blocks = 0;
human_readable_base = 1024;
output_units = 1;
break;
case 'H':
human_readable_base = 1000;
output_units = 1;
break;
case 'k':
human_blocks = 0;
kilobyte_blocks = 1;
megabyte_blocks = 0;
human_readable_base = 0;
output_units = 1024;
break;
case 'm':
human_blocks = 0;
kilobyte_blocks = 0;
megabyte_blocks = 1;
human_readable_base = 0;
output_units = 1024 * 1024;
break;
case 'T':
print_type = 1;
@@ -676,11 +624,11 @@ main (int argc, char **argv)
if (show_help)
usage (0);
if (posix_format && megabyte_blocks)
if (posix_format && output_units == 1024 * 1024)
error (1, 0, _("the option for counting 1MB blocks may not be used\n\
with the portable output format"));
if (posix_format && human_blocks)
if (posix_format && human_readable_base)
error (1, 0,
_("the option for printing with adaptive units may not be used\n\
with the portable output format"));