summaryrefslogtreecommitdiff
path: root/src/df.c
diff options
context:
space:
mode:
authorJim Meyering <jim@meyering.net>1999-11-26 16:50:24 +0000
committerJim Meyering <jim@meyering.net>1999-11-26 16:50:24 +0000
commit7af339b1262b2e5f094ec96ecb44579006fa3e94 (patch)
tree7f709095d4403d71a096bf24f7f70955ead8fc57 /src/df.c
parent0d6c8509797d9d3b5d07d425cf3c2ed9758e4d80 (diff)
downloadcoreutils-7af339b1262b2e5f094ec96ecb44579006fa3e94.tar.xz
(df_readable): Now returns char const *, not char *.
New arg NEGATIVE. (ceil_percent): Now returns double, not int. Be more careful about adding 1 to a wild value. (show_dev): Don't filter out wild sizes from the underlying operating system; instead, show them to the user as faithfully as possible.
Diffstat (limited to 'src/df.c')
-rw-r--r--src/df.c168
1 files changed, 78 insertions, 90 deletions
diff --git a/src/df.c b/src/df.c
index cbb12752a..6d79767da 100644
--- a/src/df.c
+++ b/src/df.c
@@ -196,22 +196,31 @@ excluded_fstype (const char *fstype)
}
/* Like human_readable, except return "-" if the argument is -1,
+ return the negative of N if NEGATIVE is 1,
and take ceiling of fractions if posix_format. */
-static char *
-df_readable (uintmax_t n, char *buf,
+static char const *
+df_readable (int negative, uintmax_t n, char *buf,
int from_block_size, int t_output_block_size)
{
- return (n == -1 ? "-"
- : human_readable_inexact (n, buf, from_block_size,
- t_output_block_size,
- (posix_format
- ? human_ceiling
- : human_round_to_even)));
+ if (n == -1)
+ return "-";
+ else
+ {
+ char *p = human_readable_inexact (negative ? - n : n,
+ buf + negative, from_block_size,
+ t_output_block_size,
+ (posix_format
+ ? human_ceiling
+ : human_round_to_even));
+ if (negative)
+ *--p = '-';
+ return p;
+ }
}
/* Return the ceiling of N * 100 / D. Avoid the ceil function, so that
we needn't link the math library. */
-static int
+static double
ceil_percent (uintmax_t n, uintmax_t d)
{
if (n <= (uintmax_t) -1 / 100)
@@ -227,8 +236,10 @@ ceil_percent (uintmax_t n, uintmax_t d)
practice it is quite rare to overflow uintmax_t, so this is
good enough for now. */
double pct = n * 100.0 / d;
- int r = pct;
- return r + (r != pct);
+ double ipct = (int) pct;
+ if (ipct - 1 < pct && pct <= ipct + 1)
+ pct = ipct + (ipct < pct);
+ return pct;
}
}
@@ -246,6 +257,18 @@ show_dev (const char *disk, const char *mount_point, const char *fstype,
{
struct fs_usage fsu;
const char *stat_file;
+ char buf[3][LONGEST_HUMAN_READABLE + 2];
+ int width;
+ int use_width;
+ int input_units;
+ int output_units;
+ uintmax_t total;
+ uintmax_t available;
+ int negate_available;
+ uintmax_t available_to_root;
+ uintmax_t used;
+ int negate_used;
+ uintmax_t nonroot_total;
if (me_remote && show_local_fs)
return;
@@ -300,92 +323,57 @@ show_dev (const char *disk, const char *mount_point, const char *fstype,
if (inode_format)
{
- char buf[3][LONGEST_HUMAN_READABLE + 1];
- double inodes_percent_used;
- uintmax_t inodes_used;
- int inode_units = output_block_size < 0 ? output_block_size : 1;
-
- if (fsu.fsu_files == -1 || fsu.fsu_files < fsu.fsu_ffree)
- {
- inodes_used = -1;
- inodes_percent_used = -1;
- }
- else
- {
- inodes_used = fsu.fsu_files - fsu.fsu_ffree;
- inodes_percent_used =
- (fsu.fsu_files == 0 ? 0
- : inodes_used * 100.0 / fsu.fsu_files);
- }
-
- printf (" %7s %7s %7s ",
- df_readable (fsu.fsu_files, buf[0], 1, inode_units),
- df_readable (inodes_used, buf[1], 1, inode_units),
- df_readable (fsu.fsu_ffree, buf[2], 1, inode_units));
-
- if (inodes_percent_used < 0)
- printf (" - ");
- else
- printf ("%4.0f%%", inodes_percent_used);
+ width = 7;
+ use_width = 5;
+ input_units = 1;
+ output_units = output_block_size < 0 ? output_block_size : 1;
+ total = fsu.fsu_files;
+ available = fsu.fsu_ffree;
+ negate_available = 0;
+ available_to_root = available;
}
else
{
- int w = output_block_size < 0 ? 5 : 9;
- char buf[2][LONGEST_HUMAN_READABLE + 1];
- char availbuf[LONGEST_HUMAN_READABLE + 2];
- char *avail;
- double blocks_percent_used;
- uintmax_t blocks_used;
-
- if (fsu.fsu_blocks == -1 || fsu.fsu_blocks < fsu.fsu_bfree)
- {
- blocks_used = -1;
- blocks_percent_used = -1;
- }
- else
+ width = output_block_size < 0 ? 5 : 9;
+ use_width = posix_format ? 8 : 4;
+ input_units = fsu.fsu_blocksize;
+ output_units = output_block_size;
+ total = fsu.fsu_blocks;
+ available = fsu.fsu_bavail;
+ negate_available = fsu.fsu_bavail_top_bit_set;
+ available_to_root = fsu.fsu_bfree;
+ }
+
+ used = -1;
+ negate_used = 0;
+ if (total != -1 && available_to_root != -1)
+ {
+ used = total - available_to_root;
+ if (total < available_to_root)
{
- uintmax_t blocks_avail;
-
- blocks_used = fsu.fsu_blocks - fsu.fsu_bfree;
- blocks_avail = blocks_used + fsu.fsu_bavail;
- blocks_percent_used =
- ((fsu.fsu_bavail == -1
- || blocks_avail == 0
- || (fsu.fsu_bavail_top_bit_set
- ? blocks_used < - fsu.fsu_bavail
- : fsu.fsu_bfree < fsu.fsu_bavail))
- ? -1
- : posix_format
- ? ceil_percent (blocks_used, blocks_avail)
- : blocks_used * 100.0 / blocks_avail);
+ negate_used = 1;
+ used = - used;
}
-
- avail = df_readable ((fsu.fsu_bavail_top_bit_set
- ? - fsu.fsu_bavail
- : fsu.fsu_bavail),
- availbuf + 1, fsu.fsu_blocksize,
- output_block_size);
-
- if (fsu.fsu_bavail_top_bit_set)
- *--avail = '-';
-
- printf (" %*s %*s %*s ",
- w, df_readable (fsu.fsu_blocks, buf[0], fsu.fsu_blocksize,
- output_block_size),
- w, df_readable (blocks_used, buf[1], fsu.fsu_blocksize,
- output_block_size),
- w, avail);
-
- {
- int use_width = posix_format ? 8 : 4;
-
- if (blocks_percent_used < 0)
- printf ("%*s", use_width, "- ");
- else
- printf ("%*.0f%%", use_width - 1, blocks_percent_used);
- }
}
+ printf (" %*s %*s %*s ",
+ width, df_readable (0, total,
+ buf[0], input_units, output_units),
+ width, df_readable (negate_used, used,
+ buf[1], input_units, output_units),
+ width, df_readable (negate_available, available,
+ buf[2], input_units, output_units));
+
+ if (used == -1 || available == -1
+ || ! (nonroot_total = ((negate_used ? - used : used)
+ + (negate_available ? - available : available))))
+ printf ("%*s", use_width, "- ");
+ else
+ printf ("%*.0f%%", use_width - 1,
+ (posix_format
+ ? ceil_percent (used, nonroot_total)
+ : used * 100.0 / nonroot_total));
+
if (mount_point)
{
#ifdef HIDE_AUTOMOUNT_PREFIX