[prev in list] [next in list] [prev in thread] [next in thread]
List: busybox
Subject: [PATCH 1/1] du: add -b option (print apparent size in bytes, rather than disk usage)
From: Alexander Mikhalitsyn <alexander () mihalicyn ! com>
Date: 2020-02-15 13:31:53
Message-ID: 20200215133153.4258-2-alexander () mihalicyn ! com
[Download RAW message or body]
Signed-off-by: Alexander Mikhalitsyn <alexander@mihalicyn.com>
---
coreutils/du.c | 70 ++++++++++++++++++++++++++++++++++++++++++--------
1 file changed, 60 insertions(+), 10 deletions(-)
diff --git a/coreutils/du.c b/coreutils/du.c
index d14d9e4ea..abf9d2ef0 100644
--- a/coreutils/du.c
+++ b/coreutils/du.c
@@ -57,6 +57,7 @@
//usage: IF_NOT_FEATURE_DU_DEFAULT_BLOCKSIZE_1K(
//usage: "\n Default unit is 512 bytes"
//usage: )
+//usage: "\n -b Print apparent sizes in bytes, rather than disk blocks usage"
//usage:
//usage:#define du_example_usage
//usage: "$ du\n"
@@ -84,8 +85,9 @@ enum {
OPT_d_maxdepth = (1 << 6),
OPT_l_hardlinks = (1 << 7),
OPT_c_total = (1 << 8),
- OPT_h_for_humans = (1 << 9),
- OPT_m_mbytes = (1 << 10),
+ OPT_b_apparent_size = (1 << 9),
+ OPT_h_for_humans = (1 << 10),
+ OPT_m_mbytes = (1 << 11),
};
struct globals {
@@ -94,6 +96,7 @@ struct globals {
#else
unsigned disp_k;
#endif
+ unsigned int size_unit;
int max_print_depth;
bool status;
int slink_depth;
@@ -120,21 +123,43 @@ static void print(unsigned long long size, const char *filename)
size += (G.disp_unit-1) / (unsigned)(512 * 2);
# endif
printf("%s\t%s\n",
- /* size x 512 / G.disp_unit.
+ /* size x G.size_unit / G.disp_unit.
* If G.disp_unit == 0, show one fractional
* and use suffixes
*/
- make_human_readable_str(size, 512, G.disp_unit),
+ make_human_readable_str(size, G.size_unit, G.disp_unit),
filename);
#else
if (G.disp_k) {
- size++;
- size >>= 1;
+ if (option_mask32 & OPT_b_apparent_size) {
+ size += 1023;
+ size >>= 10;
+ } else {
+ size++;
+ size >>= 1;
+ }
}
+
printf("%llu\t%s\n", size, filename);
#endif
}
+static ALWAYS_INLINE unsigned long long file_size(struct stat *statbufp)
+{
+ if (option_mask32 & OPT_b_apparent_size) {
+ /*
+ * Yes, we need to return MAX(0, statbufp->st_size)
+ * this is weird but, please, refer to
+ * 9d308df13271a852aee7d46c65432fa84145ea31 commit
+ * (maint: handle file sizes more reliably)
+ * in GNU coreutils
+ */
+ return MAX(0, statbufp->st_size);
+ } else {
+ return statbufp->st_blocks;
+ }
+}
+
/* tiny recursive du */
static unsigned long long du(const char *filename)
{
@@ -155,7 +180,7 @@ static unsigned long long du(const char *filename)
}
}
- sum = statbuf.st_blocks;
+ sum = file_size(&statbuf);
if (S_ISLNK(statbuf.st_mode)) {
if (G.slink_depth > G.du_depth) { /* -H or -L */
@@ -164,7 +189,7 @@ static unsigned long long du(const char *filename)
G.status = EXIT_FAILURE;
return 0;
}
- sum = statbuf.st_blocks;
+ sum = file_size(&statbuf);
if (G.slink_depth == 1) {
/* Convert -H to -L */
G.slink_depth = INT_MAX;
@@ -241,11 +266,14 @@ int du_main(int argc UNUSED_PARAM, char **argv)
*/
#if ENABLE_FEATURE_HUMAN_READABLE
opt = getopt32(argv, "^"
- "aHkLsxd:+lchm"
+ "aHkLsxd:+lcbhm"
"\0" "h-km:k-hm:m-hk:H-L:L-H:s-d:d-s",
&G.max_print_depth
);
argv += optind;
+ if (opt & OPT_b_apparent_size) {
+ G.disp_unit = 1;
+ }
if (opt & OPT_h_for_humans) {
G.disp_unit = 0;
}
@@ -257,7 +285,7 @@ int du_main(int argc UNUSED_PARAM, char **argv)
}
#else
opt = getopt32(argv, "^"
- "aHkLsxd:+lc"
+ "aHkLsxd:+lcb"
"\0" "H-L:L-H:s-d:d-s",
&G.max_print_depth
);
@@ -266,8 +294,30 @@ int du_main(int argc UNUSED_PARAM, char **argv)
if (opt & OPT_k_kbytes) {
G.disp_k = 1;
}
+#else
+ /*
+ * If FEATURE_DU_DEFAULT_BLOCKSIZE_1K is enabled
+ * we have already set G.disp_k = 1 but this is incorrect.
+ * For example, if we called du -b we need to
+ * print size in bytes not in KBytes.
+ */
+ if (!(opt & OPT_k_kbytes) && (opt & OPT_b_apparent_size)) {
+ G.disp_k = 0;
+ }
#endif
#endif
+
+ /*
+ * When OPT_b_apparent_size is enabled file_size()
+ * function will return sb->st_size instead of
+ * sb->st_blocks therefore we need to assume
+ * that "block" size is 1.
+ */
+ G.size_unit = 512;
+ if (opt & OPT_b_apparent_size) {
+ G.size_unit = 1;
+ }
+
if (opt & OPT_H_follow_links) {
G.slink_depth = 1;
}
--
2.19.1
_______________________________________________
busybox mailing list
busybox@busybox.net
http://lists.busybox.net/mailman/listinfo/busybox
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic