summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2008-08-28 22:42:52 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2008-08-28 22:42:52 +0000
commitd66aa3c701ffb83343239e71a8b294407ff5df86 (patch)
treeeeebccfe994962aa8a33312c8726eac5adf63f5a
parent3b80cac953b0627ba9b3337d3f9386678d436871 (diff)
downloadbusybox-w32-d66aa3c701ffb83343239e71a8b294407ff5df86.tar.gz
busybox-w32-d66aa3c701ffb83343239e71a8b294407ff5df86.tar.bz2
busybox-w32-d66aa3c701ffb83343239e71a8b294407ff5df86.zip
df: add support for more options, add some coreutils 6.10 compat.
by Bernhard Reutner-Fischer function old new delta df_main 664 795 +131 packed_usage 24812 24862 +50 make_human_readable_str 213 262 +49 static.ignored_mounts - 8 +8 static.unit_chars - 7 +7 static.zero_and_units 6 - -6 ------------------------------------------------------------------------------ (add/remove: 2/1 grow/shrink: 3/0 up/down: 245/-6) Total: 239 bytes
-rw-r--r--coreutils/Config.in6
-rw-r--r--coreutils/df.c93
-rw-r--r--include/usage.h40
-rw-r--r--libbb/human_readable.c33
-rw-r--r--scripts/defconfig2
5 files changed, 105 insertions, 69 deletions
diff --git a/coreutils/Config.in b/coreutils/Config.in
index 413839035..29b55d4ec 100644
--- a/coreutils/Config.in
+++ b/coreutils/Config.in
@@ -136,12 +136,12 @@ config DF
136 df reports the amount of disk space used and available 136 df reports the amount of disk space used and available
137 on filesystems. 137 on filesystems.
138 138
139config FEATURE_DF_INODE 139config FEATURE_DF_FANCY
140 bool "Enable -i (inode information)" 140 bool "Enable -a, -i, -B"
141 default n 141 default n
142 depends on DF 142 depends on DF
143 help 143 help
144 This option enables support for df -i. 144 This option enables -a, -i and -B.
145 145
146config DIRNAME 146config DIRNAME
147 bool "dirname" 147 bool "dirname"
diff --git a/coreutils/df.c b/coreutils/df.c
index 9cb328aa3..fd2502309 100644
--- a/coreutils/df.c
+++ b/coreutils/df.c
@@ -8,7 +8,7 @@
8 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 8 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
9 */ 9 */
10 10
11/* BB_AUDIT SUSv3 _NOT_ compliant -- options -P and -t missing. Also blocksize. */ 11/* BB_AUDIT SUSv3 _NOT_ compliant -- option -t missing. */
12/* http://www.opengroup.org/onlinepubs/007904975/utilities/df.html */ 12/* http://www.opengroup.org/onlinepubs/007904975/utilities/df.html */
13 13
14/* Mar 16, 2003 Manuel Novoa III (mjn3@codepoet.org) 14/* Mar 16, 2003 Manuel Novoa III (mjn3@codepoet.org)
@@ -16,6 +16,10 @@
16 * Size reduction. Removed floating point dependency. Added error checking 16 * Size reduction. Removed floating point dependency. Added error checking
17 * on output. Output stats on 0-sized filesystems if specifically listed on 17 * on output. Output stats on 0-sized filesystems if specifically listed on
18 * the command line. Properly round *-blocks, Used, and Available quantities. 18 * the command line. Properly round *-blocks, Used, and Available quantities.
19 *
20 * Aug 28, 2008 Bernhard Reutner-Fischer
21 *
22 * Implement -P and -B; better coreutils compat; cleanup
19 */ 23 */
20 24
21#include <mntent.h> 25#include <mntent.h>
@@ -34,51 +38,73 @@ int df_main(int argc, char **argv)
34{ 38{
35 unsigned long blocks_used; 39 unsigned long blocks_used;
36 unsigned blocks_percent_used; 40 unsigned blocks_percent_used;
37#if ENABLE_FEATURE_HUMAN_READABLE 41 unsigned long df_disp_hr = 1024;
38 unsigned df_disp_hr = 1024;
39#endif
40 int status = EXIT_SUCCESS; 42 int status = EXIT_SUCCESS;
41 unsigned opt; 43 unsigned opt;
42 FILE *mount_table; 44 FILE *mount_table;
43 struct mntent *mount_entry; 45 struct mntent *mount_entry;
44 struct statfs s; 46 struct statfs s;
45 /* default display is kilobytes */ 47 static const char ignored_mounts[] ALIGN1 =
46 const char *disp_units_hdr = "1k-blocks"; 48 "rootfs\0";
47 49
48 enum { 50 enum {
49 OPT_ALL = (1 << 0), 51 OPT_KILO = (1 << 0),
50 OPT_INODE = (ENABLE_FEATURE_HUMAN_READABLE ? (1 << 4) : (1 << 2)) 52 OPT_POSIX = (1 << 1),
51 * ENABLE_FEATURE_DF_INODE 53 OPT_ALL = (1 << 2) * ENABLE_FEATURE_DF_FANCY,
54 OPT_INODE = (1 << 3) * ENABLE_FEATURE_DF_FANCY,
55 OPT_BSIZE = (1 << 4) * ENABLE_FEATURE_DF_FANCY,
56 OPT_HUMAN = (1 << 5) * ENABLE_FEATURE_HUMAN_READABLE,
57 OPT_MEGA = (1 << 6) * ENABLE_FEATURE_HUMAN_READABLE,
52 }; 58 };
59 const char *disp_units_hdr = NULL;
60 char *chp;
53 61
54#if ENABLE_FEATURE_HUMAN_READABLE 62#if ENABLE_FEATURE_HUMAN_READABLE && ENABLE_FEATURE_DF_FANCY
55 opt_complementary = "h-km:k-hm:m-hk"; 63 opt_complementary = "k-mB:m-Bk:B-km";
56 opt = getopt32(argv, "ahmk" USE_FEATURE_DF_INODE("i")); 64#elif ENABLE_FEATURE_HUMAN_READABLE
57 if (opt & (1 << 1)) { // -h 65 opt_complementary = "k-m:m-k";
66#endif
67 opt = getopt32(argv, "kP"
68 USE_FEATURE_DF_FANCY("aiB:")
69 USE_FEATURE_HUMAN_READABLE("hm")
70 USE_FEATURE_DF_FANCY(, &chp));
71 if (opt & OPT_MEGA)
72 df_disp_hr = 1024*1024;
73
74 if (opt & OPT_BSIZE)
75 df_disp_hr = xatoul_range(chp, 1, ULONG_MAX); /* disallow 0 */
76
77 /* From the manpage of df from coreutils-6.10:
78 Disk space is shown in 1K blocks by default, unless the environment
79 variable POSIXLY_CORRECT is set, in which case 512-byte blocks are used.
80 */
81 if (getenv("POSIXLY_CORRECT")) /* TODO - a new libbb function? */
82 df_disp_hr = 512;
83
84 if (opt & OPT_HUMAN) {
58 df_disp_hr = 0; 85 df_disp_hr = 0;
59 disp_units_hdr = " Size"; 86 disp_units_hdr = " Size";
60 } 87 }
61 if (opt & (1 << 2)) { // -m 88 if (opt & OPT_INODE)
62 df_disp_hr = 1024*1024;
63 disp_units_hdr = "1M-blocks";
64 }
65 if (opt & OPT_INODE) {
66 disp_units_hdr = " Inodes"; 89 disp_units_hdr = " Inodes";
67 } 90
91 if (disp_units_hdr == NULL) {
92#if ENABLE_FEATURE_HUMAN_READABLE
93 disp_units_hdr = xasprintf("%s-blocks",
94 make_human_readable_str(df_disp_hr, 0, !!(opt & OPT_POSIX)));
68#else 95#else
69 opt = getopt32(argv, "ak" USE_FEATURE_DF_INODE("i")); 96 disp_units_hdr = xasprintf("%d-blocks", df_disp_hr);
70#endif 97#endif
71 98 }
72 printf("Filesystem %-15sUsed Available Use%% Mounted on\n", 99 printf("Filesystem %-15sUsed Available %s Mounted on\n",
73 disp_units_hdr); 100 disp_units_hdr, (opt & OPT_POSIX) ? "Capacity" : "Use%");
74 101
75 mount_table = NULL; 102 mount_table = NULL;
76 argv += optind; 103 argv += optind;
77 if (optind >= argc) { 104 if (optind >= argc) {
78 mount_table = setmntent(bb_path_mtab_file, "r"); 105 mount_table = setmntent(bb_path_mtab_file, "r");
79 if (!mount_table) { 106 if (!mount_table)
80 bb_perror_msg_and_die(bb_path_mtab_file); 107 bb_perror_msg_and_die(bb_path_mtab_file);
81 }
82 } 108 }
83 109
84 while (1) { 110 while (1) {
@@ -93,9 +119,8 @@ int df_main(int argc, char **argv)
93 } 119 }
94 } else { 120 } else {
95 mount_point = *argv++; 121 mount_point = *argv++;
96 if (!mount_point) { 122 if (!mount_point)
97 break; 123 break;
98 }
99 mount_entry = find_mount_point(mount_point, bb_path_mtab_file); 124 mount_entry = find_mount_point(mount_point, bb_path_mtab_file);
100 if (!mount_entry) { 125 if (!mount_entry) {
101 bb_error_msg("%s: can't find mount point", mount_point); 126 bb_error_msg("%s: can't find mount point", mount_point);
@@ -118,10 +143,9 @@ int df_main(int argc, char **argv)
118 s.f_blocks = s.f_files; 143 s.f_blocks = s.f_files;
119 s.f_bavail = s.f_bfree = s.f_ffree; 144 s.f_bavail = s.f_bfree = s.f_ffree;
120 s.f_bsize = 1; 145 s.f_bsize = 1;
121#if ENABLE_FEATURE_HUMAN_READABLE 146
122 if (df_disp_hr) 147 if (df_disp_hr)
123 df_disp_hr = 1; 148 df_disp_hr = 1;
124#endif
125 } 149 }
126 blocks_used = s.f_blocks - s.f_bfree; 150 blocks_used = s.f_blocks - s.f_bfree;
127 blocks_percent_used = 0; 151 blocks_percent_used = 0;
@@ -131,11 +155,10 @@ int df_main(int argc, char **argv)
131 ) / (blocks_used + s.f_bavail); 155 ) / (blocks_used + s.f_bavail);
132 } 156 }
133 157
134#ifdef WHY_IT_SHOULD_BE_HIDDEN 158 /* GNU coreutils 6.10 skip certain mounts, try to be compatible. */
135 if (strcmp(device, "rootfs") == 0) { 159 if (index_in_strings(device, ignored_mounts) != -1)
136 continue; 160 continue;
137 } 161
138#endif
139#ifdef WHY_WE_DO_IT_FOR_DEV_ROOT_ONLY 162#ifdef WHY_WE_DO_IT_FOR_DEV_ROOT_ONLY
140/* ... and also this is the only user of find_block_device */ 163/* ... and also this is the only user of find_block_device */
141 if (strcmp(device, "/dev/root") == 0) { 164 if (strcmp(device, "/dev/root") == 0) {
@@ -164,12 +187,12 @@ int df_main(int argc, char **argv)
164#else 187#else
165 printf(" %9lu %9lu %9lu %3u%% %s\n", 188 printf(" %9lu %9lu %9lu %3u%% %s\n",
166 kscale(s.f_blocks, s.f_bsize), 189 kscale(s.f_blocks, s.f_bsize),
167 kscale(s.f_blocks-s.f_bfree, s.f_bsize), 190 kscale(s.f_blocks - s.f_bfree, s.f_bsize),
168 kscale(s.f_bavail, s.f_bsize), 191 kscale(s.f_bavail, s.f_bsize),
169 blocks_percent_used, mount_point); 192 blocks_percent_used, mount_point);
170#endif 193#endif
171 } 194 }
172 } 195 }
173 196
174 fflush_stdout_and_exit(status); 197 return status;
175} 198}
diff --git a/include/usage.h b/include/usage.h
index 41012afc1..a09f7eac2 100644
--- a/include/usage.h
+++ b/include/usage.h
@@ -705,36 +705,40 @@
705 "\n do not poll for events" \ 705 "\n do not poll for events" \
706 ) 706 )
707 707
708/* -k is accepted but ignored for !HUMAN_READABLE,
709 * but we won't mention this (unimportant) */
710#if ENABLE_FEATURE_HUMAN_READABLE || ENABLE_FEATURE_DF_INODE
711#define DF_HAS_OPTIONS(x) x
712#else
713#define DF_HAS_OPTIONS(x)
714#endif
715#define df_trivial_usage \ 708#define df_trivial_usage \
716 DF_HAS_OPTIONS("[-") \ 709 "[-Pk" \
717 USE_FEATURE_HUMAN_READABLE("hmk") USE_FEATURE_DF_INODE("i") \ 710 USE_FEATURE_HUMAN_READABLE("mh") \
718 DF_HAS_OPTIONS("] ") "[FILESYSTEM...]" 711 USE_FEATURE_DF_FANCY("ai] [-B SIZE") \
712 "] [FILESYSTEM...]"
719#define df_full_usage "\n\n" \ 713#define df_full_usage "\n\n" \
720 "Print filesystem usage statistics\n" \ 714 "Print filesystem usage statistics\n" \
721 DF_HAS_OPTIONS("\nOptions:") \ 715 "\nOptions:" \
716 "\n -P POSIX output format" \
717 "\n -k 1024-byte blocks (default)" \
722 USE_FEATURE_HUMAN_READABLE( \ 718 USE_FEATURE_HUMAN_READABLE( \
719 "\n -m 1M-byte blocks" \
723 "\n -h Human readable (e.g. 1K 243M 2G)" \ 720 "\n -h Human readable (e.g. 1K 243M 2G)" \
724 "\n -m 1024*1024 blocks" \
725 "\n -k 1024 blocks" \
726 ) \ 721 ) \
727 USE_FEATURE_DF_INODE( \ 722 USE_FEATURE_DF_FANCY( \
723 "\n -a Show all filesystems" \
728 "\n -i Inodes" \ 724 "\n -i Inodes" \
729 ) 725 "\n -B SIZE Blocksize" \
726 ) \
727
730#define df_example_usage \ 728#define df_example_usage \
731 "$ df\n" \ 729 "$ df\n" \
732 "Filesystem 1k-blocks Used Available Use% Mounted on\n" \ 730 "Filesystem 1K-blocks Used Available Use% Mounted on\n" \
733 "/dev/sda3 8690864 8553540 137324 98% /\n" \ 731 "/dev/sda3 8690864 8553540 137324 98% /\n" \
734 "/dev/sda1 64216 36364 27852 57% /boot\n" \ 732 "/dev/sda1 64216 36364 27852 57% /boot\n" \
735 "$ df /dev/sda3\n" \ 733 "$ df /dev/sda3\n" \
736 "Filesystem 1k-blocks Used Available Use% Mounted on\n" \ 734 "Filesystem 1K-blocks Used Available Use% Mounted on\n" \
737 "/dev/sda3 8690864 8553540 137324 98% /\n" 735 "/dev/sda3 8690864 8553540 137324 98% /\n" \
736 "$ POSIXLY_CORRECT=sure df /dev/sda3\n" \
737 "Filesystem 512B-blocks Used Available Use% Mounted on\n" \
738 "/dev/sda3 17381728 17107080 274648 98% /\n" \
739 "$ POSIXLY_CORRECT=yep df -P /dev/sda3\n" \
740 "Filesystem 512-blocks Used Available Capacity Mounted on\n" \
741 "/dev/sda3 17381728 17107080 274648 98% /\n"
738 742
739#define dhcprelay_trivial_usage \ 743#define dhcprelay_trivial_usage \
740 "[client1,client2,...] [server_device]" 744 "[client1,client2,...] [server_device]"
diff --git a/libbb/human_readable.c b/libbb/human_readable.c
index dad26edcf..61c856750 100644
--- a/libbb/human_readable.c
+++ b/libbb/human_readable.c
@@ -32,7 +32,9 @@ const char* FAST_FUNC make_human_readable_str(unsigned long long size,
32 unsigned long block_size, unsigned long display_unit) 32 unsigned long block_size, unsigned long display_unit)
33{ 33{
34 /* The code will adjust for additional (appended) units */ 34 /* The code will adjust for additional (appended) units */
35 static const char zero_and_units[] ALIGN1 = { '0', 0, 'k', 'M', 'G', 'T' }; 35 static const char unit_chars[] ALIGN1 = {
36 '\0', 'K', 'M', 'G', 'T', 'P', 'E'
37 };
36 static const char fmt[] ALIGN1 = "%llu"; 38 static const char fmt[] ALIGN1 = "%llu";
37 static const char fmt_tenths[] ALIGN1 = "%llu.%d%c"; 39 static const char fmt_tenths[] ALIGN1 = "%llu.%d%c";
38 40
@@ -42,26 +44,33 @@ const char* FAST_FUNC make_human_readable_str(unsigned long long size,
42 int frac; 44 int frac;
43 const char *u; 45 const char *u;
44 const char *f; 46 const char *f;
47 smallint no_tenths;
45 48
46 u = zero_and_units; 49 if (size == 0)
47 f = fmt; 50 return "0";
48 frac = 0;
49 51
50 val = size * block_size; 52 /* If block_size is 0 then do not print tenths */
51 if (val == 0) { 53 no_tenths = 0;
52 return u; 54 if (block_size == 0) {
55 no_tenths = 1;
56 block_size = 1;
53 } 57 }
54 58
59 u = unit_chars;
60 val = size * block_size;
61 f = fmt;
62 frac = 0;
63
55 if (display_unit) { 64 if (display_unit) {
56 val += display_unit/2; /* Deal with rounding */ 65 val += display_unit/2; /* Deal with rounding */
57 val /= display_unit; /* Don't combine with the line above!!! */ 66 val /= display_unit; /* Don't combine with the line above!!! */
67 /* will just print it as ulonglong (below) */
58 } else { 68 } else {
59 ++u;
60 while ((val >= 1024) 69 while ((val >= 1024)
61 && (u < zero_and_units + sizeof(zero_and_units) - 1) 70 && (u < unit_chars + sizeof(unit_chars) - 1)
62 ) { 71 ) {
63 f = fmt_tenths; 72 f = fmt_tenths;
64 ++u; 73 u++;
65 frac = (((int)(val % 1024)) * 10 + 1024/2) / 1024; 74 frac = (((int)(val % 1024)) * 10 + 1024/2) / 1024;
66 val /= 1024; 75 val /= 1024;
67 } 76 }
@@ -69,9 +78,9 @@ const char* FAST_FUNC make_human_readable_str(unsigned long long size,
69 ++val; 78 ++val;
70 frac = 0; 79 frac = 0;
71 } 80 }
72#if 0 81#if 1
73 /* Sample code to omit decimal point and tenths digit. */ 82 /* Sample code to omit decimal point and tenths digit. */
74 if (/* no_tenths */ 1) { 83 if (no_tenths) {
75 if (frac >= 5) { 84 if (frac >= 5) {
76 ++val; 85 ++val;
77 } 86 }
diff --git a/scripts/defconfig b/scripts/defconfig
index 686974b74..96c1978ff 100644
--- a/scripts/defconfig
+++ b/scripts/defconfig
@@ -153,7 +153,7 @@ CONFIG_DD=y
153CONFIG_FEATURE_DD_SIGNAL_HANDLING=y 153CONFIG_FEATURE_DD_SIGNAL_HANDLING=y
154CONFIG_FEATURE_DD_IBS_OBS=y 154CONFIG_FEATURE_DD_IBS_OBS=y
155CONFIG_DF=y 155CONFIG_DF=y
156CONFIG_FEATURE_DF_INODE=y 156CONFIG_FEATURE_DF_FANCY=y
157CONFIG_DIRNAME=y 157CONFIG_DIRNAME=y
158CONFIG_DOS2UNIX=y 158CONFIG_DOS2UNIX=y
159CONFIG_UNIX2DOS=y 159CONFIG_UNIX2DOS=y