aboutsummaryrefslogtreecommitdiff
path: root/miscutils
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2014-10-06 12:50:22 +0100
committerRon Yorston <rmy@pobox.com>2014-10-06 12:50:22 +0100
commitb04d11dcbadda2620743a1dd923938f2f3043a38 (patch)
tree971afe425a81304b79e44122e220c7a69efe2616 /miscutils
parent124bbf02948b7ac0babb4ead04acd1559db182d3 (diff)
parent760d035699c4a878f9109544c1d35ea0d5f6b76c (diff)
downloadbusybox-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.src16
-rw-r--r--miscutils/Kbuild.src1
-rw-r--r--miscutils/less.c69
-rw-r--r--miscutils/taskset.c86
-rw-r--r--miscutils/ubi_tools.c23
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
502config 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
509config 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
518config TIME 502config 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
39lib-$(CONFIG_RX) += rx.o 39lib-$(CONFIG_RX) += rx.o
40lib-$(CONFIG_SETSID) += setsid.o 40lib-$(CONFIG_SETSID) += setsid.o
41lib-$(CONFIG_STRINGS) += strings.o 41lib-$(CONFIG_STRINGS) += strings.o
42lib-$(CONFIG_TASKSET) += taskset.o
43lib-$(CONFIG_TIME) += time.o 42lib-$(CONFIG_TIME) += time.o
44lib-$(CONFIG_TIMEOUT) += timeout.o 43lib-$(CONFIG_TIMEOUT) += timeout.o
45lib-$(CONFIG_TTYSIZE) += ttysize.o 44lib-$(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;