diff options
author | Ron Yorston <rmy@pobox.com> | 2014-10-06 12:50:22 +0100 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2014-10-06 12:50:22 +0100 |
commit | b04d11dcbadda2620743a1dd923938f2f3043a38 (patch) | |
tree | 971afe425a81304b79e44122e220c7a69efe2616 /miscutils | |
parent | 124bbf02948b7ac0babb4ead04acd1559db182d3 (diff) | |
parent | 760d035699c4a878f9109544c1d35ea0d5f6b76c (diff) | |
download | busybox-w32-b04d11dcbadda2620743a1dd923938f2f3043a38.tar.gz busybox-w32-b04d11dcbadda2620743a1dd923938f2f3043a38.tar.bz2 busybox-w32-b04d11dcbadda2620743a1dd923938f2f3043a38.zip |
Merge branch 'busybox' into merge
Diffstat (limited to 'miscutils')
-rw-r--r-- | miscutils/Config.src | 16 | ||||
-rw-r--r-- | miscutils/Kbuild.src | 1 | ||||
-rw-r--r-- | miscutils/less.c | 69 | ||||
-rw-r--r-- | miscutils/taskset.c | 86 | ||||
-rw-r--r-- | miscutils/ubi_tools.c | 23 |
5 files changed, 131 insertions, 64 deletions
diff --git a/miscutils/Config.src b/miscutils/Config.src index 1b2a3ae9a..d69abf1a2 100644 --- a/miscutils/Config.src +++ b/miscutils/Config.src | |||
@@ -499,22 +499,6 @@ config STRINGS | |||
499 | strings prints the printable character sequences for each file | 499 | strings prints the printable character sequences for each file |
500 | specified. | 500 | specified. |
501 | 501 | ||
502 | config TASKSET | ||
503 | bool "taskset" | ||
504 | default n # doesn't build on some non-x86 targets (m68k) | ||
505 | help | ||
506 | Retrieve or set a processes's CPU affinity. | ||
507 | This requires sched_{g,s}etaffinity support in your libc. | ||
508 | |||
509 | config FEATURE_TASKSET_FANCY | ||
510 | bool "Fancy output" | ||
511 | default y | ||
512 | depends on TASKSET | ||
513 | help | ||
514 | Add code for fancy output. This merely silences a compiler-warning | ||
515 | and adds about 135 Bytes. May be needed for machines with alot | ||
516 | of CPUs. | ||
517 | |||
518 | config TIME | 502 | config TIME |
519 | bool "time" | 503 | bool "time" |
520 | default y | 504 | default y |
diff --git a/miscutils/Kbuild.src b/miscutils/Kbuild.src index 8eaa82de9..7b449e6e8 100644 --- a/miscutils/Kbuild.src +++ b/miscutils/Kbuild.src | |||
@@ -39,7 +39,6 @@ lib-$(CONFIG_RUNLEVEL) += runlevel.o | |||
39 | lib-$(CONFIG_RX) += rx.o | 39 | lib-$(CONFIG_RX) += rx.o |
40 | lib-$(CONFIG_SETSID) += setsid.o | 40 | lib-$(CONFIG_SETSID) += setsid.o |
41 | lib-$(CONFIG_STRINGS) += strings.o | 41 | lib-$(CONFIG_STRINGS) += strings.o |
42 | lib-$(CONFIG_TASKSET) += taskset.o | ||
43 | lib-$(CONFIG_TIME) += time.o | 42 | lib-$(CONFIG_TIME) += time.o |
44 | lib-$(CONFIG_TIMEOUT) += timeout.o | 43 | lib-$(CONFIG_TIMEOUT) += timeout.o |
45 | lib-$(CONFIG_TTYSIZE) += ttysize.o | 44 | lib-$(CONFIG_TTYSIZE) += ttysize.o |
diff --git a/miscutils/less.c b/miscutils/less.c index d84df469c..554e54687 100644 --- a/miscutils/less.c +++ b/miscutils/less.c | |||
@@ -414,10 +414,10 @@ static void read_lines(void) | |||
414 | char *current_line, *p; | 414 | char *current_line, *p; |
415 | int w = width; | 415 | int w = width; |
416 | char last_terminated = terminated; | 416 | char last_terminated = terminated; |
417 | time_t last_time = 0; | ||
418 | int retry_EAGAIN = 2; | ||
417 | #if ENABLE_FEATURE_LESS_REGEXP | 419 | #if ENABLE_FEATURE_LESS_REGEXP |
418 | unsigned old_max_fline = max_fline; | 420 | unsigned old_max_fline = max_fline; |
419 | time_t last_time = 0; | ||
420 | int had_progress = 2; | ||
421 | #endif | 421 | #endif |
422 | 422 | ||
423 | /* (careful: max_fline can be -1) */ | 423 | /* (careful: max_fline can be -1) */ |
@@ -427,17 +427,14 @@ static void read_lines(void) | |||
427 | if (option_mask32 & FLAG_N) | 427 | if (option_mask32 & FLAG_N) |
428 | w -= 8; | 428 | w -= 8; |
429 | 429 | ||
430 | IF_FEATURE_LESS_REGEXP(again0:) | ||
431 | |||
432 | p = current_line = ((char*)xmalloc(w + 4)) + 4; | 430 | p = current_line = ((char*)xmalloc(w + 4)) + 4; |
433 | max_fline += last_terminated; | ||
434 | if (!last_terminated) { | 431 | if (!last_terminated) { |
435 | const char *cp = flines[max_fline]; | 432 | const char *cp = flines[max_fline]; |
436 | strcpy(p, cp); | 433 | p = stpcpy(p, cp); |
437 | p += strlen(current_line); | 434 | free(MEMPTR(cp)); |
438 | free(MEMPTR(flines[max_fline])); | ||
439 | /* last_line_pos is still valid from previous read_lines() */ | 435 | /* last_line_pos is still valid from previous read_lines() */ |
440 | } else { | 436 | } else { |
437 | max_fline++; | ||
441 | last_line_pos = 0; | 438 | last_line_pos = 0; |
442 | } | 439 | } |
443 | 440 | ||
@@ -448,15 +445,29 @@ static void read_lines(void) | |||
448 | char c; | 445 | char c; |
449 | /* if no unprocessed chars left, eat more */ | 446 | /* if no unprocessed chars left, eat more */ |
450 | if (readpos >= readeof) { | 447 | if (readpos >= readeof) { |
451 | errno = 0; | 448 | int flags = ndelay_on(0); |
452 | ndelay_on(0); | 449 | |
453 | eof_error = safe_read(STDIN_FILENO, readbuf, sizeof(readbuf)); | 450 | while (1) { |
454 | ndelay_off(0); | 451 | time_t t; |
452 | |||
453 | errno = 0; | ||
454 | eof_error = safe_read(STDIN_FILENO, readbuf, sizeof(readbuf)); | ||
455 | if (errno != EAGAIN) | ||
456 | break; | ||
457 | t = time(NULL); | ||
458 | if (t != last_time) { | ||
459 | last_time = t; | ||
460 | if (--retry_EAGAIN < 0) | ||
461 | break; | ||
462 | } | ||
463 | sched_yield(); | ||
464 | } | ||
465 | fcntl(0, F_SETFL, flags); /* ndelay_off(0) */ | ||
455 | readpos = 0; | 466 | readpos = 0; |
456 | readeof = eof_error; | 467 | readeof = eof_error; |
457 | if (eof_error <= 0) | 468 | if (eof_error <= 0) |
458 | goto reached_eof; | 469 | goto reached_eof; |
459 | IF_FEATURE_LESS_REGEXP(had_progress = 1;) | 470 | retry_EAGAIN = 1; |
460 | } | 471 | } |
461 | c = readbuf[readpos]; | 472 | c = readbuf[readpos]; |
462 | /* backspace? [needed for manpages] */ | 473 | /* backspace? [needed for manpages] */ |
@@ -491,6 +502,11 @@ static void read_lines(void) | |||
491 | *p++ = c; | 502 | *p++ = c; |
492 | *p = '\0'; | 503 | *p = '\0'; |
493 | } /* end of "read chars until we have a line" loop */ | 504 | } /* end of "read chars until we have a line" loop */ |
505 | #if 0 | ||
506 | //BUG: also triggers on this: | ||
507 | // { printf "\nfoo\n"; sleep 1; printf "\nbar\n"; } | less | ||
508 | // (resulting in lost empty line between "foo" and "bar" lines) | ||
509 | // the "terminated" logic needs fixing (or explaining) | ||
494 | /* Corner case: linewrap with only "" wrapping to next line */ | 510 | /* Corner case: linewrap with only "" wrapping to next line */ |
495 | /* Looks ugly on screen, so we do not store this empty line */ | 511 | /* Looks ugly on screen, so we do not store this empty line */ |
496 | if (!last_terminated && !current_line[0]) { | 512 | if (!last_terminated && !current_line[0]) { |
@@ -498,6 +514,7 @@ static void read_lines(void) | |||
498 | max_lineno++; | 514 | max_lineno++; |
499 | continue; | 515 | continue; |
500 | } | 516 | } |
517 | #endif | ||
501 | reached_eof: | 518 | reached_eof: |
502 | last_terminated = terminated; | 519 | last_terminated = terminated; |
503 | flines = xrealloc_vector(flines, 8, max_fline); | 520 | flines = xrealloc_vector(flines, 8, max_fline); |
@@ -528,24 +545,7 @@ static void read_lines(void) | |||
528 | #endif | 545 | #endif |
529 | } | 546 | } |
530 | if (eof_error <= 0) { | 547 | if (eof_error <= 0) { |
531 | #if !ENABLE_FEATURE_LESS_REGEXP | ||
532 | break; | 548 | break; |
533 | #else | ||
534 | if (wanted_match < num_matches) { | ||
535 | break; | ||
536 | } /* else: goto_match() called us */ | ||
537 | if (errno == EAGAIN) { | ||
538 | time_t t = time(NULL); | ||
539 | if (t != last_time) { | ||
540 | last_time = t; | ||
541 | if (--had_progress < 0) | ||
542 | break; | ||
543 | } | ||
544 | sched_yield(); | ||
545 | goto again0; | ||
546 | } | ||
547 | break; | ||
548 | #endif | ||
549 | } | 549 | } |
550 | max_fline++; | 550 | max_fline++; |
551 | current_line = ((char*)xmalloc(w + 4)) + 4; | 551 | current_line = ((char*)xmalloc(w + 4)) + 4; |
@@ -802,11 +802,18 @@ static void buffer_print(void) | |||
802 | unsigned i; | 802 | unsigned i; |
803 | 803 | ||
804 | move_cursor(0, 0); | 804 | move_cursor(0, 0); |
805 | for (i = 0; i <= max_displayed_line; i++) | 805 | for (i = 0; i <= max_displayed_line; i++) { |
806 | if (pattern_valid) | 806 | if (pattern_valid) |
807 | print_found(buffer[i]); | 807 | print_found(buffer[i]); |
808 | else | 808 | else |
809 | print_ascii(buffer[i]); | 809 | print_ascii(buffer[i]); |
810 | } | ||
811 | if ((option_mask32 & FLAG_E) | ||
812 | && eof_error <= 0 | ||
813 | && (max_fline - cur_fline) <= max_displayed_line | ||
814 | ) { | ||
815 | less_exit(EXIT_SUCCESS); | ||
816 | } | ||
810 | status_print(); | 817 | status_print(); |
811 | } | 818 | } |
812 | 819 | ||
diff --git a/miscutils/taskset.c b/miscutils/taskset.c index 4a9e3230d..2646e1dab 100644 --- a/miscutils/taskset.c +++ b/miscutils/taskset.c | |||
@@ -6,6 +6,25 @@ | |||
6 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. | 6 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. |
7 | */ | 7 | */ |
8 | 8 | ||
9 | //config:config TASKSET | ||
10 | //config: bool "taskset" | ||
11 | //config: default n # doesn't build on some non-x86 targets (m68k) | ||
12 | //config: help | ||
13 | //config: Retrieve or set a processes's CPU affinity. | ||
14 | //config: This requires sched_{g,s}etaffinity support in your libc. | ||
15 | //config: | ||
16 | //config:config FEATURE_TASKSET_FANCY | ||
17 | //config: bool "Fancy output" | ||
18 | //config: default y | ||
19 | //config: depends on TASKSET | ||
20 | //config: help | ||
21 | //config: Add code for fancy output. This merely silences a compiler-warning | ||
22 | //config: and adds about 135 Bytes. May be needed for machines with alot | ||
23 | //config: of CPUs. | ||
24 | |||
25 | //applet:IF_TASKSET(APPLET(taskset, BB_DIR_USR_BIN, BB_SUID_DROP)) | ||
26 | //kbuild:lib-$(CONFIG_TASKSET) += taskset.o | ||
27 | |||
9 | //usage:#define taskset_trivial_usage | 28 | //usage:#define taskset_trivial_usage |
10 | //usage: "[-p] [MASK] [PID | PROG ARGS]" | 29 | //usage: "[-p] [MASK] [PID | PROG ARGS]" |
11 | //usage:#define taskset_full_usage "\n\n" | 30 | //usage:#define taskset_full_usage "\n\n" |
@@ -22,6 +41,11 @@ | |||
22 | //usage: "pid 6671's new affinity mask: 1\n" | 41 | //usage: "pid 6671's new affinity mask: 1\n" |
23 | //usage: "$ taskset -p 1\n" | 42 | //usage: "$ taskset -p 1\n" |
24 | //usage: "pid 1's current affinity mask: 3\n" | 43 | //usage: "pid 1's current affinity mask: 3\n" |
44 | /* | ||
45 | Not yet implemented: | ||
46 | * -a/--all-tasks (affect all threads) | ||
47 | * -c/--cpu-list (specify CPUs via "1,3,5-7") | ||
48 | */ | ||
25 | 49 | ||
26 | #include <sched.h> | 50 | #include <sched.h> |
27 | #include "libbb.h" | 51 | #include "libbb.h" |
@@ -128,17 +152,65 @@ int taskset_main(int argc UNUSED_PARAM, char **argv) | |||
128 | current_new += 8; /* "new" */ | 152 | current_new += 8; /* "new" */ |
129 | } | 153 | } |
130 | 154 | ||
131 | { /* Affinity was specified, translate it into cpu_set_t */ | 155 | /* Affinity was specified, translate it into cpu_set_t */ |
156 | CPU_ZERO(&mask); | ||
157 | if (!ENABLE_FEATURE_TASKSET_FANCY) { | ||
132 | unsigned i; | 158 | unsigned i; |
159 | unsigned long long m; | ||
160 | |||
133 | /* Do not allow zero mask: */ | 161 | /* Do not allow zero mask: */ |
134 | unsigned long long m = xstrtoull_range(aff, 0, 1, ULLONG_MAX); | 162 | m = xstrtoull_range(aff, 0, 1, ULLONG_MAX); |
135 | enum { CNT_BIT = CPU_SETSIZE < sizeof(m)*8 ? CPU_SETSIZE : sizeof(m)*8 }; | 163 | i = 0; |
164 | do { | ||
165 | if (m & 1) | ||
166 | CPU_SET(i, &mask); | ||
167 | i++; | ||
168 | m >>= 1; | ||
169 | } while (m != 0); | ||
170 | } else { | ||
171 | unsigned i; | ||
172 | char *last_byte; | ||
173 | char *bin; | ||
174 | uint8_t bit_in_byte; | ||
175 | |||
176 | /* Cheap way to get "long enough" buffer */ | ||
177 | bin = xstrdup(aff); | ||
178 | |||
179 | if (aff[0] != '0' || (aff[1]|0x20) != 'x') { | ||
180 | /* TODO: decimal/octal masks are still limited to 2^64 */ | ||
181 | unsigned long long m = xstrtoull_range(aff, 0, 1, ULLONG_MAX); | ||
182 | bin += strlen(bin); | ||
183 | last_byte = bin - 1; | ||
184 | while (m) { | ||
185 | *--bin = m & 0xff; | ||
186 | m >>= 8; | ||
187 | } | ||
188 | } else { | ||
189 | /* aff is "0x.....", we accept very long masks in this form */ | ||
190 | last_byte = hex2bin(bin, aff + 2, INT_MAX); | ||
191 | if (!last_byte) { | ||
192 | bad_aff: | ||
193 | bb_error_msg_and_die("bad affinity '%s'", aff); | ||
194 | } | ||
195 | last_byte--; /* now points to the last byte */ | ||
196 | } | ||
136 | 197 | ||
137 | CPU_ZERO(&mask); | 198 | i = 0; |
138 | for (i = 0; i < CNT_BIT; i++) { | 199 | bit_in_byte = 1; |
139 | unsigned long long bit = (1ULL << i); | 200 | while (last_byte >= bin) { |
140 | if (bit & m) | 201 | if (bit_in_byte & *last_byte) { |
202 | if (i >= CPU_SETSIZE) | ||
203 | goto bad_aff; | ||
141 | CPU_SET(i, &mask); | 204 | CPU_SET(i, &mask); |
205 | //bb_error_msg("bit %d set", i); | ||
206 | } | ||
207 | i++; | ||
208 | /* bit_in_byte is uint8_t! & 0xff is implied */ | ||
209 | bit_in_byte = (bit_in_byte << 1); | ||
210 | if (!bit_in_byte) { | ||
211 | bit_in_byte = 1; | ||
212 | last_byte--; | ||
213 | } | ||
142 | } | 214 | } |
143 | } | 215 | } |
144 | 216 | ||
diff --git a/miscutils/ubi_tools.c b/miscutils/ubi_tools.c index b71393532..6c09fe534 100644 --- a/miscutils/ubi_tools.c +++ b/miscutils/ubi_tools.c | |||
@@ -125,12 +125,24 @@ int ubi_tools_main(int argc UNUSED_PARAM, char **argv) | |||
125 | strcpy(path, "/sys/class/ubi/ubi"); | 125 | strcpy(path, "/sys/class/ubi/ubi"); |
126 | memset(&req_structs, 0, sizeof(req_structs)); | 126 | memset(&req_structs, 0, sizeof(req_structs)); |
127 | 127 | ||
128 | #define OPTION_m (1 << 0) | ||
129 | #define OPTION_d (1 << 1) | ||
130 | #define OPTION_n (1 << 2) | ||
131 | #define OPTION_N (1 << 3) | ||
132 | #define OPTION_s (1 << 4) | ||
133 | #define OPTION_a (1 << 5) | ||
134 | #define OPTION_t (1 << 6) | ||
128 | if (do_mkvol) { | 135 | if (do_mkvol) { |
129 | opt_complementary = "-1:d+:n+:a+"; | 136 | opt_complementary = "-1:d+:n+:a+"; |
130 | opts = getopt32(argv, "md:n:N:s:a:t:", | 137 | opts = getopt32(argv, "md:n:N:s:a:t:", |
131 | &dev_num, &vol_id, | 138 | &dev_num, &vol_id, |
132 | &vol_name, &size_bytes_str, &alignment, &type | 139 | &vol_name, &size_bytes_str, &alignment, &type |
133 | ); | 140 | ); |
141 | } else | ||
142 | if (do_update) { | ||
143 | opt_complementary = "-1"; | ||
144 | opts = getopt32(argv, "s:at", &size_bytes_str); | ||
145 | opts *= OPTION_s; | ||
134 | } else { | 146 | } else { |
135 | opt_complementary = "-1:m+:d+:n+:a+"; | 147 | opt_complementary = "-1:m+:d+:n+:a+"; |
136 | opts = getopt32(argv, "m:d:n:N:s:a:t:", | 148 | opts = getopt32(argv, "m:d:n:N:s:a:t:", |
@@ -138,13 +150,6 @@ int ubi_tools_main(int argc UNUSED_PARAM, char **argv) | |||
138 | &vol_name, &size_bytes_str, &alignment, &type | 150 | &vol_name, &size_bytes_str, &alignment, &type |
139 | ); | 151 | ); |
140 | } | 152 | } |
141 | #define OPTION_m (1 << 0) | ||
142 | #define OPTION_d (1 << 1) | ||
143 | #define OPTION_n (1 << 2) | ||
144 | #define OPTION_N (1 << 3) | ||
145 | #define OPTION_s (1 << 4) | ||
146 | #define OPTION_a (1 << 5) | ||
147 | #define OPTION_t (1 << 6) | ||
148 | 153 | ||
149 | if (opts & OPTION_s) | 154 | if (opts & OPTION_s) |
150 | size_bytes = xatoull_sfx(size_bytes_str, size_suffixes); | 155 | size_bytes = xatoull_sfx(size_bytes_str, size_suffixes); |
@@ -302,9 +307,9 @@ int ubi_tools_main(int argc UNUSED_PARAM, char **argv) | |||
302 | if (!(opts & OPTION_s)) { | 307 | if (!(opts & OPTION_s)) { |
303 | if (!*argv) | 308 | if (!*argv) |
304 | bb_show_usage(); | 309 | bb_show_usage(); |
305 | xstat(*argv, &st); | ||
306 | size_bytes = st.st_size; | ||
307 | xmove_fd(xopen(*argv, O_RDONLY), STDIN_FILENO); | 310 | xmove_fd(xopen(*argv, O_RDONLY), STDIN_FILENO); |
311 | xfstat(STDIN_FILENO, &st, *argv); | ||
312 | size_bytes = st.st_size; | ||
308 | } | 313 | } |
309 | 314 | ||
310 | bytes64 = size_bytes; | 315 | bytes64 = size_bytes; |