aboutsummaryrefslogtreecommitdiff
path: root/coreutils
diff options
context:
space:
mode:
Diffstat (limited to 'coreutils')
-rw-r--r--coreutils/echo.c2
-rw-r--r--coreutils/env.c2
-rw-r--r--coreutils/md5_sha1_sum.c21
-rw-r--r--coreutils/nice.c2
-rw-r--r--coreutils/readlink.c2
-rw-r--r--coreutils/shuf.c2
-rw-r--r--coreutils/sort.c101
-rw-r--r--coreutils/uname.c2
-rw-r--r--coreutils/uniq.c2
-rw-r--r--coreutils/uudecode.c2
-rw-r--r--coreutils/uuencode.c2
11 files changed, 92 insertions, 48 deletions
diff --git a/coreutils/echo.c b/coreutils/echo.c
index 82f0358b6..44b2eb5d0 100644
--- a/coreutils/echo.c
+++ b/coreutils/echo.c
@@ -321,6 +321,8 @@ int echo_main(int argc, char **argv)
321 if (*arg == '0' && (unsigned char)(arg[1] - '0') < 8) { 321 if (*arg == '0' && (unsigned char)(arg[1] - '0') < 8) {
322 arg++; 322 arg++;
323 } 323 }
324//FIXME? we also accept non-0 starting sequences (see echo-prints-slash_41 test)
325// echo -ne '-\41-' prints "-!-". bash 5.0.17 does not (prints "-\41-").
324 /* bb_process_escape_sequence can handle nul correctly */ 326 /* bb_process_escape_sequence can handle nul correctly */
325 c = bb_process_escape_sequence( (void*) &arg); 327 c = bb_process_escape_sequence( (void*) &arg);
326 } 328 }
diff --git a/coreutils/env.c b/coreutils/env.c
index a0ea4dd27..6eafd06ef 100644
--- a/coreutils/env.c
+++ b/coreutils/env.c
@@ -100,7 +100,7 @@ int env_main(int argc UNUSED_PARAM, char **argv)
100 } 100 }
101 } 101 }
102 102
103 fflush_stdout_and_exit(EXIT_SUCCESS); 103 fflush_stdout_and_exit_SUCCESS();
104} 104}
105 105
106/* 106/*
diff --git a/coreutils/md5_sha1_sum.c b/coreutils/md5_sha1_sum.c
index 4efa23061..3b389cb6b 100644
--- a/coreutils/md5_sha1_sum.c
+++ b/coreutils/md5_sha1_sum.c
@@ -151,10 +151,12 @@ static unsigned char *hash_bin_to_hex(unsigned char *hash_value,
151 return (unsigned char *)hex_value; 151 return (unsigned char *)hex_value;
152} 152}
153 153
154#define BUFSZ (CONFIG_FEATURE_COPYBUF_KB < 4 ? 4096 : CONFIG_FEATURE_COPYBUF_KB * 1024)
155
154#if !ENABLE_SHA3SUM 156#if !ENABLE_SHA3SUM
155# define hash_file(f,w) hash_file(f) 157# define hash_file(b,f,w) hash_file(b,f)
156#endif 158#endif
157static uint8_t *hash_file(const char *filename, unsigned sha3_width) 159static uint8_t *hash_file(unsigned char *in_buf, const char *filename, unsigned sha3_width)
158{ 160{
159 int src_fd, hash_len, count; 161 int src_fd, hash_len, count;
160 union _ctx_ { 162 union _ctx_ {
@@ -227,8 +229,7 @@ static uint8_t *hash_file(const char *filename, unsigned sha3_width)
227 } 229 }
228 230
229 { 231 {
230 RESERVE_CONFIG_UBUFFER(in_buf, 4096); 232 while ((count = safe_read(src_fd, in_buf, BUFSZ)) > 0) {
231 while ((count = safe_read(src_fd, in_buf, 4096)) > 0) {
232 update(&context, in_buf, count); 233 update(&context, in_buf, count);
233 } 234 }
234 hash_value = NULL; 235 hash_value = NULL;
@@ -238,7 +239,6 @@ static uint8_t *hash_file(const char *filename, unsigned sha3_width)
238 final(&context, in_buf); 239 final(&context, in_buf);
239 hash_value = hash_bin_to_hex(in_buf, hash_len); 240 hash_value = hash_bin_to_hex(in_buf, hash_len);
240 } 241 }
241 RELEASE_CONFIG_BUFFER(in_buf);
242 } 242 }
243 243
244 if (src_fd != STDIN_FILENO) { 244 if (src_fd != STDIN_FILENO) {
@@ -251,6 +251,7 @@ static uint8_t *hash_file(const char *filename, unsigned sha3_width)
251int md5_sha1_sum_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 251int md5_sha1_sum_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
252int md5_sha1_sum_main(int argc UNUSED_PARAM, char **argv) 252int md5_sha1_sum_main(int argc UNUSED_PARAM, char **argv)
253{ 253{
254 unsigned char *in_buf;
254 int return_value = EXIT_SUCCESS; 255 int return_value = EXIT_SUCCESS;
255 unsigned flags; 256 unsigned flags;
256#if ENABLE_SHA3SUM 257#if ENABLE_SHA3SUM
@@ -279,6 +280,12 @@ int md5_sha1_sum_main(int argc UNUSED_PARAM, char **argv)
279 if (!*argv) 280 if (!*argv)
280 *--argv = (char*)"-"; 281 *--argv = (char*)"-";
281 282
283 /* The buffer is not alloc/freed for each input file:
284 * for big values of COPYBUF_KB, this helps to keep its pages
285 * pre-faulted and possibly even fully cached on local CPU.
286 */
287 in_buf = xmalloc(BUFSZ);
288
282 do { 289 do {
283 if (ENABLE_FEATURE_MD5_SHA1_SUM_CHECK && (flags & FLAG_CHECK)) { 290 if (ENABLE_FEATURE_MD5_SHA1_SUM_CHECK && (flags & FLAG_CHECK)) {
284 FILE *pre_computed_stream; 291 FILE *pre_computed_stream;
@@ -310,7 +317,7 @@ int md5_sha1_sum_main(int argc UNUSED_PARAM, char **argv)
310 *filename_ptr = '\0'; 317 *filename_ptr = '\0';
311 filename_ptr += 2; 318 filename_ptr += 2;
312 319
313 hash_value = hash_file(filename_ptr, sha3_width); 320 hash_value = hash_file(in_buf, filename_ptr, sha3_width);
314 321
315 if (hash_value && (strcmp((char*)hash_value, line) == 0)) { 322 if (hash_value && (strcmp((char*)hash_value, line) == 0)) {
316 if (!(flags & FLAG_SILENT)) 323 if (!(flags & FLAG_SILENT))
@@ -339,7 +346,7 @@ int md5_sha1_sum_main(int argc UNUSED_PARAM, char **argv)
339 } 346 }
340 fclose_if_not_stdin(pre_computed_stream); 347 fclose_if_not_stdin(pre_computed_stream);
341 } else { 348 } else {
342 uint8_t *hash_value = hash_file(*argv, sha3_width); 349 uint8_t *hash_value = hash_file(in_buf, *argv, sha3_width);
343 if (hash_value == NULL) { 350 if (hash_value == NULL) {
344 return_value = EXIT_FAILURE; 351 return_value = EXIT_FAILURE;
345 } else { 352 } else {
diff --git a/coreutils/nice.c b/coreutils/nice.c
index 28591ac61..e70da5d2b 100644
--- a/coreutils/nice.c
+++ b/coreutils/nice.c
@@ -33,7 +33,7 @@ int nice_main(int argc UNUSED_PARAM, char **argv)
33 33
34 if (!*++argv) { /* No args, so (GNU) output current nice value. */ 34 if (!*++argv) { /* No args, so (GNU) output current nice value. */
35 printf("%d\n", old_priority); 35 printf("%d\n", old_priority);
36 fflush_stdout_and_exit(EXIT_SUCCESS); 36 fflush_stdout_and_exit_SUCCESS();
37 } 37 }
38 38
39 adjustment = 10; /* Set default adjustment. */ 39 adjustment = 10; /* Set default adjustment. */
diff --git a/coreutils/readlink.c b/coreutils/readlink.c
index 09d69df2b..b2e867883 100644
--- a/coreutils/readlink.c
+++ b/coreutils/readlink.c
@@ -96,5 +96,5 @@ int readlink_main(int argc UNUSED_PARAM, char **argv)
96 printf((opt & 2) ? "%s" : "%s\n", buf); 96 printf((opt & 2) ? "%s" : "%s\n", buf);
97 free(buf); 97 free(buf);
98 98
99 fflush_stdout_and_exit(EXIT_SUCCESS); 99 fflush_stdout_and_exit_SUCCESS();
100} 100}
diff --git a/coreutils/shuf.c b/coreutils/shuf.c
index 81b0df453..56ba03aad 100644
--- a/coreutils/shuf.c
+++ b/coreutils/shuf.c
@@ -171,5 +171,5 @@ int shuf_main(int argc, char **argv)
171 printf("%s%c", lines[i], eol); 171 printf("%s%c", lines[i], eol);
172 } 172 }
173 173
174 fflush_stdout_and_exit(EXIT_SUCCESS); 174 fflush_stdout_and_exit_SUCCESS();
175} 175}
diff --git a/coreutils/sort.c b/coreutils/sort.c
index 32a06e40a..9aac656fe 100644
--- a/coreutils/sort.c
+++ b/coreutils/sort.c
@@ -18,7 +18,7 @@
18//config: sort is used to sort lines of text in specified files. 18//config: sort is used to sort lines of text in specified files.
19//config: 19//config:
20//config:config FEATURE_SORT_BIG 20//config:config FEATURE_SORT_BIG
21//config: bool "Full SuSv3 compliant sort (support -ktcbdfiogM)" 21//config: bool "Full SuSv3 compliant sort (support -ktcbdfioghM)"
22//config: default y 22//config: default y
23//config: depends on SORT 23//config: depends on SORT
24//config: help 24//config: help
@@ -43,7 +43,7 @@
43 43
44//usage:#define sort_trivial_usage 44//usage:#define sort_trivial_usage
45//usage: "[-nru" 45//usage: "[-nru"
46//usage: IF_FEATURE_SORT_BIG("gMcszbdfiokt] [-o FILE] [-k START[.OFS][OPTS][,END[.OFS][OPTS]] [-t CHAR") 46//usage: IF_FEATURE_SORT_BIG("ghMcszbdfiokt] [-o FILE] [-k START[.OFS][OPTS][,END[.OFS][OPTS]] [-t CHAR")
47//usage: "] [FILE]..." 47//usage: "] [FILE]..."
48//usage:#define sort_full_usage "\n\n" 48//usage:#define sort_full_usage "\n\n"
49//usage: "Sort lines of text\n" 49//usage: "Sort lines of text\n"
@@ -59,6 +59,7 @@
59//usage: "\n -n Sort numbers" 59//usage: "\n -n Sort numbers"
60//usage: IF_FEATURE_SORT_BIG( 60//usage: IF_FEATURE_SORT_BIG(
61//usage: "\n -g General numerical sort" 61//usage: "\n -g General numerical sort"
62//usage: "\n -h Sort human readable numbers (2K 1G)"
62//usage: "\n -M Sort month" 63//usage: "\n -M Sort month"
63//usage: "\n -V Sort version" 64//usage: "\n -V Sort version"
64//usage: "\n -t CHAR Field separator" 65//usage: "\n -t CHAR Field separator"
@@ -94,31 +95,32 @@
94enum { 95enum {
95 FLAG_n = 1 << 0, /* Numeric sort */ 96 FLAG_n = 1 << 0, /* Numeric sort */
96 FLAG_g = 1 << 1, /* Sort using strtod() */ 97 FLAG_g = 1 << 1, /* Sort using strtod() */
97 FLAG_M = 1 << 2, /* Sort date */ 98 FLAG_h = 1 << 2, /* Sort using strtod(), plus KMGT suffixes */
98 FLAG_V = 1 << 3, /* Sort version */ 99 FLAG_M = 1 << 3, /* Sort date */
100 FLAG_V = 1 << 4, /* Sort version */
99/* ucsz apply to root level only, not keys. b at root level implies bb */ 101/* ucsz apply to root level only, not keys. b at root level implies bb */
100 FLAG_u = 1 << 4, /* Unique */ 102 FLAG_u = 1 << 5, /* Unique */
101 FLAG_c = 1 << 5, /* Check: no output, exit(!ordered) */ 103 FLAG_c = 1 << 6, /* Check: no output, exit(!ordered) */
102 FLAG_s = 1 << 6, /* Stable sort, no ascii fallback at end */ 104 FLAG_s = 1 << 7, /* Stable sort, no ascii fallback at end */
103 FLAG_z = 1 << 7, /* Input and output is NUL terminated, not \n */ 105 FLAG_z = 1 << 8, /* Input and output is NUL terminated, not \n */
104/* These can be applied to search keys, the previous four can't */ 106/* These can be applied to search keys, the previous four can't */
105 FLAG_b = 1 << 8, /* Ignore leading blanks */ 107 FLAG_b = 1 << 9, /* Ignore leading blanks */
106 FLAG_r = 1 << 9, /* Reverse */ 108 FLAG_r = 1 << 10, /* Reverse */
107 FLAG_d = 1 << 10, /* Ignore !(isalnum()|isspace()) */ 109 FLAG_d = 1 << 11, /* Ignore !(isalnum()|isspace()) */
108 FLAG_f = 1 << 11, /* Force uppercase */ 110 FLAG_f = 1 << 12, /* Force uppercase */
109 FLAG_i = 1 << 12, /* Ignore !isprint() */ 111 FLAG_i = 1 << 13, /* Ignore !isprint() */
110 FLAG_m = 1 << 13, /* ignored: merge already sorted files; do not sort */ 112 FLAG_m = 1 << 14, /* ignored: merge already sorted files; do not sort */
111 FLAG_S = 1 << 14, /* ignored: -S, --buffer-size=SIZE */ 113 FLAG_S = 1 << 15, /* ignored: -S, --buffer-size=SIZE */
112 FLAG_T = 1 << 15, /* ignored: -T, --temporary-directory=DIR */ 114 FLAG_T = 1 << 16, /* ignored: -T, --temporary-directory=DIR */
113 FLAG_o = 1 << 16, 115 FLAG_o = 1 << 17,
114 FLAG_k = 1 << 17, 116 FLAG_k = 1 << 18,
115 FLAG_t = 1 << 18, 117 FLAG_t = 1 << 19,
116 FLAG_bb = 0x80000000, /* Ignore trailing blanks */ 118 FLAG_bb = 0x80000000, /* Ignore trailing blanks */
117 FLAG_no_tie_break = 0x40000000, 119 FLAG_no_tie_break = 0x40000000,
118}; 120};
119 121
120static const char sort_opt_str[] ALIGN1 = "^" 122static const char sort_opt_str[] ALIGN1 = "^"
121 "ngMVucszbrdfimS:T:o:k:*t:" 123 "nghMVucszbrdfimS:T:o:k:*t:"
122 "\0" "o--o:t--t"/*-t, -o: at most one of each*/; 124 "\0" "o--o:t--t"/*-t, -o: at most one of each*/;
123/* 125/*
124 * OPT_STR must not be string literal, needs to have stable address: 126 * OPT_STR must not be string literal, needs to have stable address:
@@ -253,6 +255,25 @@ static struct sort_key *add_key(void)
253#define GET_LINE(fp) xmalloc_fgetline(fp) 255#define GET_LINE(fp) xmalloc_fgetline(fp)
254#endif 256#endif
255 257
258#if ENABLE_FEATURE_SORT_BIG
259static int scale_suffix(const char *tail)
260{
261 static const char suffix[] ALIGN1 = "kmgtpezy";
262 const char *s;
263 int n;
264
265 if (!tail[0])
266 return -1;
267 s = strchr(suffix, tail[0] | 0x20);
268 if (!s)
269 return -1;
270 n = s - suffix;
271 if (n != 0 && tail[0] >= 'a')
272 return -1; /* mg... not accepted, only MG... */
273 return n;
274}
275#endif
276
256/* Iterate through keys list and perform comparisons */ 277/* Iterate through keys list and perform comparisons */
257static int compare_keys(const void *xarg, const void *yarg) 278static int compare_keys(const void *xarg, const void *yarg)
258{ 279{
@@ -275,7 +296,7 @@ static int compare_keys(const void *xarg, const void *yarg)
275 y = *(char **)yarg; 296 y = *(char **)yarg;
276#endif 297#endif
277 /* Perform actual comparison */ 298 /* Perform actual comparison */
278 switch (flags & (FLAG_n | FLAG_g | FLAG_M | FLAG_V)) { 299 switch (flags & (FLAG_n | FLAG_g | FLAG_h | FLAG_M | FLAG_V)) {
279 default: 300 default:
280 bb_simple_error_msg_and_die("unknown sort type"); 301 bb_simple_error_msg_and_die("unknown sort type");
281 break; 302 break;
@@ -293,7 +314,8 @@ static int compare_keys(const void *xarg, const void *yarg)
293#endif 314#endif
294 break; 315 break;
295#if ENABLE_FEATURE_SORT_BIG 316#if ENABLE_FEATURE_SORT_BIG
296 case FLAG_g: { 317 case FLAG_g:
318 case FLAG_h: {
297 char *xx, *yy; 319 char *xx, *yy;
298//TODO: needs setlocale(LC_NUMERIC, "C")? 320//TODO: needs setlocale(LC_NUMERIC, "C")?
299 double dx = strtod(x, &xx); 321 double dx = strtod(x, &xx);
@@ -308,16 +330,26 @@ static int compare_keys(const void *xarg, const void *yarg)
308 retval = (dy != dy) ? 0 : -1; 330 retval = (dy != dy) ? 0 : -1;
309 else if (dy != dy) 331 else if (dy != dy)
310 retval = 1; 332 retval = 1;
311 /* Check for infinity. Could underflow, but it avoids libm. */ 333 else {
312 else if (1.0 / dx == 0.0) { 334 if (flags & FLAG_h) {
313 if (dx < 0) 335 int xs = scale_suffix(xx);
314 retval = (1.0 / dy == 0.0 && dy < 0) ? 0 : -1; 336 int ys = scale_suffix(yy);
337 if (xs != ys) {
338 retval = xs - ys;
339 break;
340 }
341 }
342 /* Check for infinity. Could underflow, but it avoids libm. */
343 if (1.0 / dx == 0.0) {
344 if (dx < 0)
345 retval = (1.0 / dy == 0.0 && dy < 0) ? 0 : -1;
346 else
347 retval = (1.0 / dy == 0.0 && dy > 0) ? 0 : 1;
348 } else if (1.0 / dy == 0.0)
349 retval = (dy < 0) ? 1 : -1;
315 else 350 else
316 retval = (1.0 / dy == 0.0 && dy > 0) ? 0 : 1; 351 retval = (dx > dy) ? 1 : ((dx < dy) ? -1 : 0);
317 } else if (1.0 / dy == 0.0) 352 }
318 retval = (dy < 0) ? 1 : -1;
319 else
320 retval = (dx > dy) ? 1 : ((dx < dy) ? -1 : 0);
321 break; 353 break;
322 } 354 }
323 case FLAG_M: { 355 case FLAG_M: {
@@ -380,7 +412,9 @@ static int compare_keys(const void *xarg, const void *yarg)
380 412
381 /* If x > y, 1, else -1 */ 413 /* If x > y, 1, else -1 */
382 retval = (x32 > y32) * 2 - 1; 414 retval = (x32 > y32) * 2 - 1;
383 } else 415 /* Here, -r has no effect! */
416 return retval;
417 }
384 if (!(option_mask32 & FLAG_no_tie_break)) { 418 if (!(option_mask32 & FLAG_no_tie_break)) {
385 /* fallback sort */ 419 /* fallback sort */
386 flags = option_mask32; 420 flags = option_mask32;
@@ -474,6 +508,7 @@ int sort_main(int argc UNUSED_PARAM, char **argv)
474 FLAG_allowed_for_k = 508 FLAG_allowed_for_k =
475 FLAG_n | /* Numeric sort */ 509 FLAG_n | /* Numeric sort */
476 FLAG_g | /* Sort using strtod() */ 510 FLAG_g | /* Sort using strtod() */
511 FLAG_h | /* Sort using strtod(), plus KMGT suffixes */
477 FLAG_M | /* Sort date */ 512 FLAG_M | /* Sort date */
478 FLAG_b | /* Ignore leading blanks */ 513 FLAG_b | /* Ignore leading blanks */
479 FLAG_r | /* Reverse */ 514 FLAG_r | /* Reverse */
@@ -644,5 +679,5 @@ int sort_main(int argc UNUSED_PARAM, char **argv)
644 printf("%s%c", lines[i], ch); 679 printf("%s%c", lines[i], ch);
645 } 680 }
646 681
647 fflush_stdout_and_exit(EXIT_SUCCESS); 682 fflush_stdout_and_exit_SUCCESS();
648} 683}
diff --git a/coreutils/uname.c b/coreutils/uname.c
index da785ab4c..6c0bdf096 100644
--- a/coreutils/uname.c
+++ b/coreutils/uname.c
@@ -209,5 +209,5 @@ int uname_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
209#endif 209#endif
210 } 210 }
211 211
212 fflush_stdout_and_exit(EXIT_SUCCESS); /* coreutils-6.9 compat */ 212 fflush_stdout_and_exit_SUCCESS(); /* coreutils-6.9 compat */
213} 213}
diff --git a/coreutils/uniq.c b/coreutils/uniq.c
index a3058ac07..06c57f750 100644
--- a/coreutils/uniq.c
+++ b/coreutils/uniq.c
@@ -139,5 +139,5 @@ int uniq_main(int argc UNUSED_PARAM, char **argv)
139 139
140 die_if_ferror(stdin, input_filename); 140 die_if_ferror(stdin, input_filename);
141 141
142 fflush_stdout_and_exit(EXIT_SUCCESS); 142 fflush_stdout_and_exit_SUCCESS();
143} 143}
diff --git a/coreutils/uudecode.c b/coreutils/uudecode.c
index e90902f52..63a8d4d48 100644
--- a/coreutils/uudecode.c
+++ b/coreutils/uudecode.c
@@ -352,7 +352,7 @@ int baseNUM_main(int argc UNUSED_PARAM, char **argv)
352#undef src_buf 352#undef src_buf
353 } 353 }
354 354
355 fflush_stdout_and_exit(EXIT_SUCCESS); 355 fflush_stdout_and_exit_SUCCESS();
356} 356}
357#endif 357#endif
358 358
diff --git a/coreutils/uuencode.c b/coreutils/uuencode.c
index db49ec80a..f096e3122 100644
--- a/coreutils/uuencode.c
+++ b/coreutils/uuencode.c
@@ -78,5 +78,5 @@ int uuencode_main(int argc UNUSED_PARAM, char **argv)
78 } 78 }
79 printf(tbl == bb_uuenc_tbl_std ? "\n`\nend\n" : "\n====\n"); 79 printf(tbl == bb_uuenc_tbl_std ? "\n`\nend\n" : "\n====\n");
80 80
81 fflush_stdout_and_exit(EXIT_SUCCESS); 81 fflush_stdout_and_exit_SUCCESS();
82} 82}