[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH v2] df: introduce option '--total'
From: |
Li Zefan |
Subject: |
[PATCH v2] df: introduce option '--total' |
Date: |
Fri, 30 Nov 2007 10:31:14 +0800 |
User-agent: |
Thunderbird 2.0.0.0 (X11/20070419) |
Introduce option '--total', and '-c' for it's short name.
This patch is based on the patch posted by Dennis Smit, but he didn't
make further effort to revise and improve the patch.
http://lists.gnu.org/archive/html/bug-coreutils/2003-11/msg00064.html
The main idea is to split a new function print_info() from show_dev(),
and thus show_grand_total() can make utilization of print_info().
There are 2 main differences between this patch and Dennis':
- In this patch, the totals are represented in bytes internally, and
converted to output units when printing.
- Dennis mistaked to take total_negate_available as type uintmax_t, and
dealt with it in a wrong way.
v2:
- Remove global variable total_negate_available. Fix the calculation of
total_available.
Any comments?
Signed-off-by: Shan Wei <address@hidden>
Signed-off-by: Li Yucai <address@hidden>
Signed-off-by: Xu Wanchao <address@hidden>
Signed-off-by: Li Zefan <address@hidden>
---
TODO | 2 -
src/df.c | 207 +++++++++++++++++++++++++++++++++++++++++---------------------
2 files changed, 137 insertions(+), 72 deletions(-)
diff --git a/TODO b/TODO
index 93f5f54..a470477 100644
--- a/TODO
+++ b/TODO
@@ -49,8 +49,6 @@ Should printf '\0123' print "\n3"?
printf: consider adapting builtins/printf.def from bash
-df: add `--total' option, suggested here http://bugs.debian.org/186007
-
seq: give better diagnostics for invalid formats:
e.g. no or too many % directives
seq: consider allowing format string to contain no %-directives
diff --git a/src/df.c b/src/df.c
index e9c82f5..4621efc 100644
--- a/src/df.c
+++ b/src/df.c
@@ -40,6 +40,9 @@
#define AUTHORS \
"Torbjorn Granlund", "David MacKenzie", "Paul Eggert"
+/* Convert data from one unit to byte. */
+#define TO_BYTE(num, size) ((num) * (size))
+
/* Name this program was run with. */
char *program_name;
@@ -69,6 +72,14 @@ static bool posix_format;
/* True if a file system has been processed for output. */
static bool file_systems_processed;
+/* If true, show the grand total. */
+static bool show_total;
+
+/* The following variables are used for storing the total statistics. */
+static uintmax_t total_total;
+static uintmax_t total_available;
+static uintmax_t total_available_to_root;
+
/* If true, invoke the `sync' system call before getting any usage data.
Using this option can make df very slow, especially with many or very
busy disks. Note that this may make a difference on some systems --
@@ -121,6 +132,7 @@ enum
static struct option const long_options[] =
{
{"all", no_argument, NULL, 'a'},
+ {"total", no_argument, NULL, 'c'},
{"block-size", required_argument, NULL, 'B'},
{"inodes", no_argument, NULL, 'i'},
{"human-readable", no_argument, NULL, 'h'},
@@ -249,71 +261,22 @@ df_readable (bool negative, uintmax_t n, char *buf,
}
}
-/* Display a space listing for the disk device with absolute file name DISK.
- If MOUNT_POINT is non-NULL, it is the name of the root of the
- file system on DISK.
- If STAT_FILE is non-null, it is the name of a file within the file
- system that the user originally asked for; this provides better
- diagnostics, and sometimes it provides better results on networked
- file systems that give different free-space results depending on
- where in the file system you probe.
- If FSTYPE is non-NULL, it is the type of the file system on DISK.
- If MOUNT_POINT is non-NULL, then DISK may be NULL -- certain systems may
- not be able to produce statistics in this case.
- ME_DUMMY and ME_REMOTE are the mount entry flags. */
-
+/* This function handles the printing of an filesystem entry.*/
static void
-show_dev (char const *disk, char const *mount_point,
- char const *stat_file, char const *fstype,
- bool me_dummy, bool me_remote)
+print_info (char const *disk, char const *mount_point,
+ char const *fstype, uintmax_t total,
+ uintmax_t available, bool negate_available,
+ uintmax_t available_to_root, uintmax_t input_units,
+ uintmax_t output_units)
{
- struct fs_usage fsu;
char buf[3][LONGEST_HUMAN_READABLE + 2];
+ uintmax_t used;
int width;
- int col1_adjustment = 0;
int use_width;
- uintmax_t input_units;
- uintmax_t output_units;
- uintmax_t total;
- uintmax_t available;
- bool negate_available;
- uintmax_t available_to_root;
- uintmax_t used;
+ int col1_adjustment = 0;
bool negate_used;
double pct = -1;
- if (me_remote & show_local_fs)
- return;
-
- if (me_dummy & !show_all_fs & !show_listed_fs)
- return;
-
- if (!selected_fstype (fstype) || excluded_fstype (fstype))
- return;
-
- /* If MOUNT_POINT is NULL, then the file system is not mounted, and this
- program reports on the file system that the special file is on.
- It would be better to report on the unmounted file system,
- but statfs doesn't do that on most systems. */
- if (!stat_file)
- stat_file = mount_point ? mount_point : disk;
-
- if (get_fs_usage (stat_file, disk, &fsu))
- {
- error (0, errno, "%s", quote (stat_file));
- exit_status = EXIT_FAILURE;
- return;
- }
-
- if (fsu.fsu_blocks == 0 && !show_all_fs && !show_listed_fs)
- return;
-
- if (! file_systems_processed)
- {
- file_systems_processed = true;
- print_header ();
- }
-
if (! disk)
disk = "-"; /* unknown */
if (! fstype)
@@ -344,11 +307,6 @@ show_dev (char const *disk, char const *mount_point,
{
width = 7;
use_width = 5;
- input_units = output_units = 1;
- total = fsu.fsu_files;
- available = fsu.fsu_ffree;
- negate_available = false;
- available_to_root = available;
}
else
{
@@ -368,13 +326,6 @@ show_dev (char const *disk, char const *mount_point,
use_width = ((posix_format
&& ! (human_output_opts & human_autoscale))
? 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 != UINTMAX_MAX));
- available_to_root = fsu.fsu_bfree;
}
used = UINTMAX_MAX;
@@ -447,6 +398,114 @@ show_dev (char const *disk, char const *mount_point,
}
putchar ('\n');
}
+
+/* Prepares an filesystem entry for the print_info function and also
+ does the stuff for the grand total static.
+ If MOUNT_POINT is non-NULL, it is the name of the root of the
+ file system on DISK.
+ If STAT_FILE is non-null, it is the name of a file within the file
+ system that the user originally asked for; this provides better
+ diagnostics, and sometimes it provides better results on networked
+ file systems that give different free-space results depending on
+ where in the file system you probe.
+ If FSTYPE is non-NULL, it is the type of the file system on DISK.
+ If MOUNT_POINT is non-NULL, then DISK may be NULL -- certain systems may
+ not be able to produce statistics in this case.
+ ME_DUMMY and ME_REMOTE are the mount entry flags. */
+
+static void
+show_dev (char const *disk, char const *mount_point,
+ char const *stat_file, char const *fstype,
+ bool me_dummy, bool me_remote)
+{
+ struct fs_usage fsu;
+ uintmax_t input_units;
+ uintmax_t output_units;
+ uintmax_t total;
+ uintmax_t available;
+ bool negate_available;
+ uintmax_t available_to_root;
+
+ if (me_remote & show_local_fs)
+ return;
+
+ if (me_dummy & !show_all_fs & !show_listed_fs)
+ return;
+
+ if (!selected_fstype (fstype) || excluded_fstype (fstype))
+ return;
+
+ /* If MOUNT_POINT is NULL, then the file system is not mounted, and this
+ program reports on the file system that the special file is on.
+ It would be better to report on the unmounted file system,
+ but statfs doesn't do that on most systems. */
+ if (!stat_file)
+ stat_file = mount_point ? mount_point : disk;
+
+ if (get_fs_usage (stat_file, disk, &fsu))
+ {
+ error (0, errno, "%s", quote (stat_file));
+ exit_status = EXIT_FAILURE;
+ return;
+ }
+
+ if (fsu.fsu_blocks == 0 && !show_all_fs && !show_listed_fs)
+ return;
+
+ if (! file_systems_processed)
+ {
+ file_systems_processed = true;
+ print_header ();
+ }
+
+ if (inode_format)
+ {
+ input_units = output_units = 1;
+ total = fsu.fsu_files;
+ available = fsu.fsu_ffree;
+ negate_available = false;
+ available_to_root = available;
+ }
+ else
+ {
+ 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 != UINTMAX_MAX));
+ available_to_root = fsu.fsu_bfree;
+ }
+
+ print_info (disk, mount_point, fstype, total, available,
+ negate_available, available_to_root, input_units, output_units);
+
+ if (show_total)
+ {
+ total_total += TO_BYTE (total, input_units);
+ total_available += TO_BYTE (available, input_units);
+ total_available_to_root += TO_BYTE (available_to_root, input_units);
+ }
+}
+
+/* Show a grand total statics. */
+static void
+show_grand_total (void)
+{
+ if (inode_format)
+ print_info ("total", NULL, NULL, total_total, total_available,
+ false, total_available_to_root, 1, 1);
+ else
+ {
+ bool total_negate_available = false;
+ if (total_available > TYPE_MAXIMUM(uintmax_t))
+ total_negate_available = true;
+
+ print_info ("total", NULL, NULL, total_total, total_available,
+ total_negate_available, total_available_to_root,
+ 1, output_block_size);
+ }
+}
/* Return the root mountpoint of the file system on which FILE exists, in
malloced storage. FILE_STAT should be the result of stating FILE.
@@ -744,6 +803,7 @@ Mandatory arguments to long options are mandatory for short
options too.\n\
"), stdout);
fputs (_("\
-a, --all include dummy file systems\n\
+ -c, --total produce a grand total\n\
-B, --block-size=SIZE use SIZE-byte 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\
@@ -794,13 +854,14 @@ main (int argc, char **argv)
human_output_opts = -1;
print_type = false;
file_systems_processed = false;
+ show_total = false;
posix_format = false;
exit_status = EXIT_SUCCESS;
for (;;)
{
int oi = -1;
- int c = getopt_long (argc, argv, "aB:iF:hHklmPTt:vx:", long_options,
+ int c = getopt_long (argc, argv, "acB:iF:hHklmPTt:vx:", long_options,
&oi);
if (c == -1)
break;
@@ -810,6 +871,9 @@ main (int argc, char **argv)
case 'a':
show_all_fs = true;
break;
+ case 'c':
+ show_total = true;
+ break;
case 'B':
{
enum strtol_error e = human_options (optarg, &human_output_opts,
@@ -961,6 +1025,9 @@ main (int argc, char **argv)
else
show_all_entries ();
+ if (show_total && file_systems_processed)
+ show_grand_total();
+
if (! file_systems_processed)
error (EXIT_FAILURE, 0, _("no file systems processed"));
--
1.5.3.rc7
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [PATCH v2] df: introduce option '--total',
Li Zefan <=