diff options
author | Ron Yorston <rmy@pobox.com> | 2018-03-01 15:37:12 +0000 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2018-03-01 15:37:12 +0000 |
commit | 5b726f8a78c33e117c2a968739b1b4a6964905f8 (patch) | |
tree | af063c6bf3e99b7480c2fad2dffc2a76c09cb5e0 /coreutils | |
parent | 5f8dac68690e92f0be220f8f8d9f797a2aedc806 (diff) | |
parent | cc222747ae7e264cbe9b1c8a9c253860275db8a9 (diff) | |
download | busybox-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.c | 32 | ||||
-rw-r--r-- | coreutils/od_bloaty.c | 18 | ||||
-rw-r--r-- | coreutils/sort.c | 97 |
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) | |||
91 | int df_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 91 | int df_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
92 | int df_main(int argc UNUSED_PARAM, char **argv) | 92 | int 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 |
223 | enum { G_pseudo_offset = 0 }; | 230 | enum { 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 | ||
854 | static 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 | |||
860 | static void | 862 | static void |
861 | format_address_std(off_t address, char c) | 863 | format_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:" | ||
98 | enum { | 89 | enum { |
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 | ||
114 | static 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 |
123 | static char key_separator; | 124 | static 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 | |||
131 | static char *get_key(char *str, struct sort_key *key, int flags) | 136 | static 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) | |||
368 | int sort_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 398 | int sort_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
369 | int sort_main(int argc UNUSED_PARAM, char **argv) | 399 | int 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]); |