aboutsummaryrefslogtreecommitdiff
path: root/coreutils
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2018-03-01 15:37:12 +0000
committerRon Yorston <rmy@pobox.com>2018-03-01 15:37:12 +0000
commit5b726f8a78c33e117c2a968739b1b4a6964905f8 (patch)
treeaf063c6bf3e99b7480c2fad2dffc2a76c09cb5e0 /coreutils
parent5f8dac68690e92f0be220f8f8d9f797a2aedc806 (diff)
parentcc222747ae7e264cbe9b1c8a9c253860275db8a9 (diff)
downloadbusybox-w32-5b726f8a78c33e117c2a968739b1b4a6964905f8.tar.gz
busybox-w32-5b726f8a78c33e117c2a968739b1b4a6964905f8.tar.bz2
busybox-w32-5b726f8a78c33e117c2a968739b1b4a6964905f8.zip
Merge branch 'busybox' into merge
Diffstat (limited to 'coreutils')
-rw-r--r--coreutils/df.c32
-rw-r--r--coreutils/od_bloaty.c18
-rw-r--r--coreutils/sort.c97
3 files changed, 103 insertions, 44 deletions
diff --git a/coreutils/df.c b/coreutils/df.c
index 4076b5fec..50dccac52 100644
--- a/coreutils/df.c
+++ b/coreutils/df.c
@@ -91,8 +91,6 @@ static unsigned long kscale(unsigned long b, unsigned long bs)
91int df_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 91int df_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
92int df_main(int argc UNUSED_PARAM, char **argv) 92int df_main(int argc UNUSED_PARAM, char **argv)
93{ 93{
94 unsigned long blocks_used;
95 unsigned blocks_percent_used;
96 unsigned long df_disp_hr = 1024; 94 unsigned long df_disp_hr = 1024;
97 int status = EXIT_SUCCESS; 95 int status = EXIT_SUCCESS;
98 unsigned opt; 96 unsigned opt;
@@ -208,6 +206,11 @@ int df_main(int argc UNUSED_PARAM, char **argv)
208 } 206 }
209 207
210 device = mount_entry->mnt_fsname; 208 device = mount_entry->mnt_fsname;
209
210 /* GNU coreutils 6.10 skips certain mounts, try to be compatible */
211 if (ENABLE_FEATURE_SKIP_ROOTFS && strcmp(device, "rootfs") == 0)
212 continue;
213
211 mount_point = mount_entry->mnt_dir; 214 mount_point = mount_entry->mnt_dir;
212 fs_type = mount_entry->mnt_type; 215 fs_type = mount_entry->mnt_type;
213 216
@@ -222,26 +225,31 @@ int df_main(int argc UNUSED_PARAM, char **argv)
222 s.f_frsize = s.f_bsize; 225 s.f_frsize = s.f_bsize;
223 226
224 if ((s.f_blocks > 0) || !mount_table || (opt & OPT_ALL)) { 227 if ((s.f_blocks > 0) || !mount_table || (opt & OPT_ALL)) {
228 unsigned long long blocks_used;
229 unsigned long long blocks_total;
230 unsigned blocks_percent_used;
231
225 if (opt & OPT_INODE) { 232 if (opt & OPT_INODE) {
226 s.f_blocks = s.f_files; 233 s.f_blocks = s.f_files;
227 s.f_bavail = s.f_bfree = s.f_ffree; 234 s.f_bavail = s.f_bfree = s.f_ffree;
228 s.f_frsize = 1; 235 s.f_frsize = 1;
229
230 if (df_disp_hr) 236 if (df_disp_hr)
231 df_disp_hr = 1; 237 df_disp_hr = 1;
232 } 238 }
233 blocks_used = s.f_blocks - s.f_bfree; 239 blocks_used = s.f_blocks - s.f_bfree;
234 blocks_percent_used = 0; 240 blocks_total = blocks_used + s.f_bavail;
235 if (blocks_used + s.f_bavail) { 241 blocks_percent_used = blocks_total; /* 0% if blocks_total == 0, else... */
236 blocks_percent_used = (blocks_used * 100ULL 242 if (blocks_total != 0) {
237 + (blocks_used + s.f_bavail)/2 243 /* Downscale sizes for narrower division */
238 ) / (blocks_used + s.f_bavail); 244 unsigned u;
245 while (blocks_total >= INT_MAX / 101) {
246 blocks_total >>= 1;
247 blocks_used >>= 1;
248 }
249 u = (unsigned)blocks_used * 100u + (unsigned)blocks_total / 2;
250 blocks_percent_used = u / (unsigned)blocks_total;
239 } 251 }
240 252
241 /* GNU coreutils 6.10 skips certain mounts, try to be compatible. */
242 if (ENABLE_FEATURE_SKIP_ROOTFS && strcmp(device, "rootfs") == 0)
243 continue;
244
245#ifdef WHY_WE_DO_IT_FOR_DEV_ROOT_ONLY 253#ifdef WHY_WE_DO_IT_FOR_DEV_ROOT_ONLY
246 if (strcmp(device, "/dev/root") == 0) { 254 if (strcmp(device, "/dev/root") == 0) {
247 /* Adjusts device to be the real root device, 255 /* Adjusts device to be the real root device,
diff --git a/coreutils/od_bloaty.c b/coreutils/od_bloaty.c
index 645a05f57..75e14ef7d 100644
--- a/coreutils/od_bloaty.c
+++ b/coreutils/od_bloaty.c
@@ -218,7 +218,14 @@ struct globals {
218 218
219 bool not_first; 219 bool not_first;
220 bool prev_pair_equal; 220 bool prev_pair_equal;
221
222 char address_fmt[sizeof("%0n"OFF_FMT"xc")];
221} FIX_ALIASING; 223} FIX_ALIASING;
224/* Corresponds to 'x' above */
225#define address_base_char G.address_fmt[sizeof(G.address_fmt)-3]
226/* Corresponds to 'n' above */
227#define address_pad_len_char G.address_fmt[2]
228
222#if !ENABLE_LONG_OPTS 229#if !ENABLE_LONG_OPTS
223enum { G_pseudo_offset = 0 }; 230enum { G_pseudo_offset = 0 };
224#endif 231#endif
@@ -227,6 +234,7 @@ enum { G_pseudo_offset = 0 };
227 setup_common_bufsiz(); \ 234 setup_common_bufsiz(); \
228 BUILD_BUG_ON(sizeof(G) > COMMON_BUFSIZE); \ 235 BUILD_BUG_ON(sizeof(G) > COMMON_BUFSIZE); \
229 G.bytes_per_block = 32; \ 236 G.bytes_per_block = 32; \
237 strcpy(G.address_fmt, "%0n"OFF_FMT"xc"); \
230} while (0) 238} while (0)
231 239
232 240
@@ -851,18 +859,12 @@ format_address_none(off_t address UNUSED_PARAM, char c UNUSED_PARAM)
851{ 859{
852} 860}
853 861
854static char address_fmt[] ALIGN1 = "%0n"OFF_FMT"xc";
855/* Corresponds to 'x' above */
856#define address_base_char address_fmt[sizeof(address_fmt)-3]
857/* Corresponds to 'n' above */
858#define address_pad_len_char address_fmt[2]
859
860static void 862static void
861format_address_std(off_t address, char c) 863format_address_std(off_t address, char c)
862{ 864{
863 /* Corresponds to 'c' */ 865 /* Corresponds to 'c' */
864 address_fmt[sizeof(address_fmt)-2] = c; 866 G.address_fmt[sizeof(G.address_fmt)-2] = c;
865 printf(address_fmt, address); 867 printf(G.address_fmt, address);
866} 868}
867 869
868#if ENABLE_LONG_OPTS 870#if ENABLE_LONG_OPTS
diff --git a/coreutils/sort.c b/coreutils/sort.c
index ceea24491..b39297a26 100644
--- a/coreutils/sort.c
+++ b/coreutils/sort.c
@@ -62,9 +62,9 @@
62//usage: "\n -u Suppress duplicate lines" 62//usage: "\n -u Suppress duplicate lines"
63//usage: IF_FEATURE_SORT_BIG( 63//usage: IF_FEATURE_SORT_BIG(
64//usage: "\n -z Lines are terminated by NUL, not newline" 64//usage: "\n -z Lines are terminated by NUL, not newline"
65////usage: "\n -m Ignored for GNU compatibility" 65///////: "\n -m Ignored for GNU compatibility"
66////usage: "\n -S BUFSZ Ignored for GNU compatibility" 66///////: "\n -S BUFSZ Ignored for GNU compatibility"
67////usage: "\n -T TMPDIR Ignored for GNU compatibility" 67///////: "\n -T TMPDIR Ignored for GNU compatibility"
68//usage: ) 68//usage: )
69//usage: 69//usage:
70//usage:#define sort_example_usage 70//usage:#define sort_example_usage
@@ -85,16 +85,7 @@
85 85
86#include "libbb.h" 86#include "libbb.h"
87 87
88/* This is a NOEXEC applet. Be very careful! */
89
90
91/*
92 sort [-m][-o output][-bdfinru][-t char][-k keydef]... [file...]
93 sort -c [-bdfinru][-t char][-k keydef][file]
94*/
95
96/* These are sort types */ 88/* These are sort types */
97#define OPT_STR "ngMucszbrdfimS:T:o:k:*t:"
98enum { 89enum {
99 FLAG_n = 1, /* Numeric sort */ 90 FLAG_n = 1, /* Numeric sort */
100 FLAG_g = 2, /* Sort using strtod() */ 91 FLAG_g = 2, /* Sort using strtod() */
@@ -117,8 +108,18 @@ enum {
117 FLAG_k = 0x10000, 108 FLAG_k = 0x10000,
118 FLAG_t = 0x20000, 109 FLAG_t = 0x20000,
119 FLAG_bb = 0x80000000, /* Ignore trailing blanks */ 110 FLAG_bb = 0x80000000, /* Ignore trailing blanks */
111 FLAG_no_tie_break = 0x40000000,
120}; 112};
121 113
114static const char sort_opt_str[] ALIGN1 = "^"
115 "ngMucszbrdfimS:T:o:k:*t:"
116 "\0" "o--o:t--t"/*-t, -o: at most one of each*/;
117/*
118 * OPT_STR must not be string literal, needs to have stable address:
119 * code uses "strchr(OPT_STR,c) - OPT_STR" idiom.
120 */
121#define OPT_STR (sort_opt_str + 1)
122
122#if ENABLE_FEATURE_SORT_BIG 123#if ENABLE_FEATURE_SORT_BIG
123static char key_separator; 124static char key_separator;
124 125
@@ -128,6 +129,10 @@ static struct sort_key {
128 unsigned flags; 129 unsigned flags;
129} *key_list; 130} *key_list;
130 131
132
133/* This is a NOEXEC applet. Be very careful! */
134
135
131static char *get_key(char *str, struct sort_key *key, int flags) 136static char *get_key(char *str, struct sort_key *key, int flags)
132{ 137{
133 int start = start; /* for compiler */ 138 int start = start; /* for compiler */
@@ -340,10 +345,35 @@ static int compare_keys(const void *xarg, const void *yarg)
340#endif 345#endif
341 } /* for */ 346 } /* for */
342 347
343 /* Perform fallback sort if necessary */ 348 if (retval == 0) {
344 if (!retval && !(option_mask32 & FLAG_s)) { 349 /* So far lines are "the same" */
345 flags = option_mask32; 350
346 retval = strcmp(*(char **)xarg, *(char **)yarg); 351 if (option_mask32 & FLAG_s) {
352 /* "Stable sort": later line is "greater than",
353 * IOW: do not allow qsort() to swap equal lines.
354 */
355 uint32_t *p32;
356 uint32_t x32, y32;
357 char *line;
358 unsigned len;
359
360 line = *(char**)xarg;
361 len = (strlen(line) + 4) & (~3u);
362 p32 = (void*)(line + len);
363 x32 = *p32;
364 line = *(char**)yarg;
365 len = (strlen(line) + 4) & (~3u);
366 p32 = (void*)(line + len);
367 y32 = *p32;
368
369 /* If x > y, 1, else -1 */
370 retval = (x32 > y32) * 2 - 1;
371 } else
372 if (!(option_mask32 & FLAG_no_tie_break)) {
373 /* fallback sort */
374 flags = option_mask32;
375 retval = strcmp(*(char **)xarg, *(char **)yarg);
376 }
347 } 377 }
348 378
349 if (flags & FLAG_r) 379 if (flags & FLAG_r)
@@ -368,7 +398,7 @@ static unsigned str2u(char **str)
368int sort_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 398int sort_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
369int sort_main(int argc UNUSED_PARAM, char **argv) 399int sort_main(int argc UNUSED_PARAM, char **argv)
370{ 400{
371 char *line, **lines; 401 char **lines;
372 char *str_ignored, *str_o, *str_t; 402 char *str_ignored, *str_o, *str_t;
373 llist_t *lst_k = NULL; 403 llist_t *lst_k = NULL;
374 int i; 404 int i;
@@ -378,9 +408,8 @@ int sort_main(int argc UNUSED_PARAM, char **argv)
378 xfunc_error_retval = 2; 408 xfunc_error_retval = 2;
379 409
380 /* Parse command line options */ 410 /* Parse command line options */
381 opts = getopt32(argv, "^" 411 opts = getopt32(argv,
382 OPT_STR 412 sort_opt_str,
383 "\0" "o--o:t--t"/*-t, -o: at most one of each*/,
384 &str_ignored, &str_ignored, &str_o, &lst_k, &str_t 413 &str_ignored, &str_ignored, &str_o, &lst_k, &str_t
385 ); 414 );
386 /* global b strips leading and trailing spaces */ 415 /* global b strips leading and trailing spaces */
@@ -457,7 +486,7 @@ int sort_main(int argc UNUSED_PARAM, char **argv)
457 * do not continue to next file: */ 486 * do not continue to next file: */
458 FILE *fp = xfopen_stdin(*argv); 487 FILE *fp = xfopen_stdin(*argv);
459 for (;;) { 488 for (;;) {
460 line = GET_LINE(fp); 489 char *line = GET_LINE(fp);
461 if (!line) 490 if (!line)
462 break; 491 break;
463 lines = xrealloc_vector(lines, 6, linecount); 492 lines = xrealloc_vector(lines, 6, linecount);
@@ -482,15 +511,35 @@ int sort_main(int argc UNUSED_PARAM, char **argv)
482 return EXIT_SUCCESS; 511 return EXIT_SUCCESS;
483 } 512 }
484#endif 513#endif
514
515 /* For stable sort, store original line position beyond terminating NUL */
516 if (option_mask32 & FLAG_s) {
517 for (i = 0; i < linecount; i++) {
518 uint32_t *p32;
519 char *line;
520 unsigned len;
521
522 line = lines[i];
523 len = (strlen(line) + 4) & (~3u);
524 lines[i] = line = xrealloc(line, len + 4);
525 p32 = (void*)(line + len);
526 *p32 = i;
527 }
528 /*option_mask32 |= FLAG_no_tie_break;*/
529 /* ^^^redundant: if FLAG_s, compare_keys() does no tie break */
530 }
531
485 /* Perform the actual sort */ 532 /* Perform the actual sort */
486 qsort(lines, linecount, sizeof(lines[0]), compare_keys); 533 qsort(lines, linecount, sizeof(lines[0]), compare_keys);
487 534
488 /* Handle -u */ 535 /* Handle -u */
489 if (option_mask32 & FLAG_u) { 536 if (option_mask32 & FLAG_u) {
490 int j = 0; 537 int j = 0;
491 /* coreutils 6.3 drop lines for which only key is the same */ 538 /* coreutils 6.3 drop lines for which only key is the same
492 /* -- disabling last-resort compare... */ 539 * -- disabling last-resort compare, or else compare_keys()
493 option_mask32 |= FLAG_s; 540 * will be the same only for completely identical lines.
541 */
542 option_mask32 |= FLAG_no_tie_break;
494 for (i = 1; i < linecount; i++) { 543 for (i = 1; i < linecount; i++) {
495 if (compare_keys(&lines[j], &lines[i]) == 0) 544 if (compare_keys(&lines[j], &lines[i]) == 0)
496 free(lines[i]); 545 free(lines[i]);