*
* Licensed under GPLv2 or later, see file LICENSE in this source tree.
*/
-
-/* BB_AUDIT SUSv3 compliant (unless default blocksize set to 1k) */
-/* http://www.opengroup.org/onlinepubs/007904975/utilities/du.html */
-
/* Mar 16, 2003 Manuel Novoa III (mjn3@codepoet.org)
*
* Mostly rewritten for SUSv3 compliance and to fix bugs/defects.
* 3) Added error checking of output.
* 4) Fixed busybox bug #1284 involving long overflow with human_readable.
*/
+//config:config DU
+//config: bool "du (default blocksize of 512 bytes)"
+//config: default y
+//config: help
+//config: du is used to report the amount of disk space used
+//config: for specified files.
+//config:
+//config:config FEATURE_DU_DEFAULT_BLOCKSIZE_1K
+//config: bool "Use a default blocksize of 1024 bytes (1K)"
+//config: default y
+//config: depends on DU
+//config: help
+//config: Use a blocksize of (1K) instead of the default 512b.
+
+//applet:IF_DU(APPLET(du, BB_DIR_USR_BIN, BB_SUID_DROP))
+
+//kbuild:lib-$(CONFIG_DU) += du.o
+
+/* BB_AUDIT SUSv3 compliant (unless default blocksize set to 1k) */
+/* http://www.opengroup.org/onlinepubs/007904975/utilities/du.html */
//usage:#define du_trivial_usage
//usage: "[-aHLdclsx" IF_FEATURE_HUMAN_READABLE("hm") "k] [FILE]..."
//usage:#define du_full_usage "\n\n"
-//usage: "Summarize disk space used for each FILE and/or directory.\n"
-//usage: "Disk space is printed in units of "
-//usage: IF_FEATURE_DU_DEFAULT_BLOCKSIZE_1K("1024")
-//usage: IF_NOT_FEATURE_DU_DEFAULT_BLOCKSIZE_1K("512")
-//usage: " bytes.\n"
-//usage: "\nOptions:"
+//usage: "Summarize disk space used for each FILE and/or directory\n"
//usage: "\n -a Show file sizes too"
//usage: "\n -L Follow all symlinks"
//usage: "\n -H Follow symlinks on command line"
//usage: "\n -s Display only a total for each argument"
//usage: "\n -x Skip directories on different filesystems"
//usage: IF_FEATURE_HUMAN_READABLE(
-//usage: "\n -h Sizes in human readable format (e.g., 1K 243M 2G )"
+//usage: "\n -h Sizes in human readable format (e.g., 1K 243M 2G)"
//usage: "\n -m Sizes in megabytes"
//usage: )
-//usage: "\n -k Sizes in kilobytes"
-//usage: IF_FEATURE_DU_DEFAULT_BLOCKSIZE_1K(" (default)")
+//usage: "\n -k Sizes in kilobytes" IF_FEATURE_DU_DEFAULT_BLOCKSIZE_1K(" (default)")
+//usage: IF_NOT_FEATURE_DU_DEFAULT_BLOCKSIZE_1K(
+//usage: "\n Default unit is 512 bytes"
+//usage: )
//usage:
//usage:#define du_example_usage
//usage: "$ du\n"
//usage: "2417 .\n"
#include "libbb.h"
+#include "common_bufsiz.h"
enum {
OPT_a_files_too = (1 << 0),
struct globals {
#if ENABLE_FEATURE_HUMAN_READABLE
- unsigned long disp_hr;
+ unsigned long disp_unit;
#else
unsigned disp_k;
#endif
int du_depth;
dev_t dir_dev;
} FIX_ALIASING;
-#define G (*(struct globals*)&bb_common_bufsiz1)
+#define G (*(struct globals*)bb_common_bufsiz1)
+#define INIT_G() do { setup_common_bufsiz(); } while (0)
-static void print(unsigned long size, const char *filename)
+static void print(unsigned long long size, const char *filename)
{
/* TODO - May not want to defer error checking here. */
#if ENABLE_FEATURE_HUMAN_READABLE
+# if ENABLE_DESKTOP
+ /* ~30 bytes of code for extra comtat:
+ * coreutils' du rounds sizes up:
+ * for example, 1025k file is shown as "2" by du -m.
+ * We round to nearest if human-readable [too hard to fix],
+ * else (fixed scale such as -m), we round up. To that end,
+ * add yet another half of the unit before displaying:
+ */
+ if (G.disp_unit)
+ size += (G.disp_unit-1) / (unsigned)(512 * 2);
+# endif
printf("%s\t%s\n",
- /* size x 512 / G.disp_hr, show one fractional,
- * use suffixes if G.disp_hr == 0 */
- make_human_readable_str(size, 512, G.disp_hr),
+ /* size x 512 / G.disp_unit.
+ * If G.disp_unit == 0, show one fractional
+ * and use suffixes
+ */
+ make_human_readable_str(size, 512, G.disp_unit),
filename);
#else
if (G.disp_k) {
size++;
size >>= 1;
}
- printf("%lu\t%s\n", size, filename);
+ printf("%llu\t%s\n", size, filename);
#endif
}
/* tiny recursive du */
-static unsigned long du(const char *filename)
+static unsigned long long du(const char *filename)
{
struct stat statbuf;
- unsigned long sum;
+ unsigned long long sum;
if (lstat(filename, &statbuf) != 0) {
bb_simple_perror_msg(filename);
int du_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
int du_main(int argc UNUSED_PARAM, char **argv)
{
- unsigned long total;
+ unsigned long long total;
int slink_depth_save;
unsigned opt;
+ INIT_G();
+
#if ENABLE_FEATURE_HUMAN_READABLE
- IF_FEATURE_DU_DEFAULT_BLOCKSIZE_1K(G.disp_hr = 1024;)
- IF_NOT_FEATURE_DU_DEFAULT_BLOCKSIZE_1K(G.disp_hr = 512;)
+ IF_FEATURE_DU_DEFAULT_BLOCKSIZE_1K(G.disp_unit = 1024;)
+ IF_NOT_FEATURE_DU_DEFAULT_BLOCKSIZE_1K(G.disp_unit = 512;)
if (getenv("POSIXLY_CORRECT")) /* TODO - a new libbb function? */
- G.disp_hr = 512;
+ G.disp_unit = 512;
#else
IF_FEATURE_DU_DEFAULT_BLOCKSIZE_1K(G.disp_k = 1;)
/* IF_NOT_FEATURE_DU_DEFAULT_BLOCKSIZE_1K(G.disp_k = 0;) - G is pre-zeroed */
* ignore -a. This is consistent with -s being equivalent to -d 0.
*/
#if ENABLE_FEATURE_HUMAN_READABLE
- opt_complementary = "h-km:k-hm:m-hk:H-L:L-H:s-d:d-s:d+";
- opt = getopt32(argv, "aHkLsx" "d:" "lc" "hm", &G.max_print_depth);
+ opt = getopt32(argv, "^"
+ "aHkLsxd:+lchm"
+ "\0" "h-km:k-hm:m-hk:H-L:L-H:s-d:d-s",
+ &G.max_print_depth
+ );
argv += optind;
if (opt & OPT_h_for_humans) {
- G.disp_hr = 0;
+ G.disp_unit = 0;
}
if (opt & OPT_m_mbytes) {
- G.disp_hr = 1024*1024;
+ G.disp_unit = 1024*1024;
}
if (opt & OPT_k_kbytes) {
- G.disp_hr = 1024;
+ G.disp_unit = 1024;
}
#else
- opt_complementary = "H-L:L-H:s-d:d-s:d+";
- opt = getopt32(argv, "aHkLsx" "d:" "lc", &G.max_print_depth);
+ opt = getopt32(argv, "^"
+ "aHkLsxd:+lc"
+ "\0" "H-L:L-H:s-d:d-s",
+ &G.max_print_depth
+ );
argv += optind;
#if !ENABLE_FEATURE_DU_DEFAULT_BLOCKSIZE_1K
if (opt & OPT_k_kbytes) {