diff options
-rw-r--r-- | include/libbb.h | 1 | ||||
-rw-r--r-- | libbb/xfuncs.c | 46 | ||||
-rw-r--r-- | procps/top.c | 39 |
3 files changed, 48 insertions, 38 deletions
diff --git a/include/libbb.h b/include/libbb.h index 89a1695fa..678c56109 100644 --- a/include/libbb.h +++ b/include/libbb.h | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <stddef.h> | 27 | #include <stddef.h> |
28 | #include <string.h> | 28 | #include <string.h> |
29 | /* #include <strings.h> - said to be obsolete */ | 29 | /* #include <strings.h> - said to be obsolete */ |
30 | #include <sys/poll.h> | ||
30 | #include <sys/ioctl.h> | 31 | #include <sys/ioctl.h> |
31 | #include <sys/mman.h> | 32 | #include <sys/mman.h> |
32 | #include <sys/socket.h> | 33 | #include <sys/socket.h> |
diff --git a/libbb/xfuncs.c b/libbb/xfuncs.c index fa9fc10d6..140c7bb6f 100644 --- a/libbb/xfuncs.c +++ b/libbb/xfuncs.c | |||
@@ -284,35 +284,44 @@ void smart_ulltoa5(unsigned long long ul, char buf[5]) | |||
284 | { | 284 | { |
285 | const char *fmt; | 285 | const char *fmt; |
286 | char c; | 286 | char c; |
287 | unsigned v,idx = 0; | 287 | unsigned v, u, idx = 0; |
288 | ul *= 10; | 288 | |
289 | if (ul > 9999*10) { // do not scale if 9999 or less | 289 | if (ul > 9999) { // do not scale if 9999 or less |
290 | while (ul >= 10000) { | 290 | ul *= 10; |
291 | do { | ||
291 | ul /= 1024; | 292 | ul /= 1024; |
292 | idx++; | 293 | idx++; |
293 | } | 294 | } while (ul >= 10000); |
294 | } | 295 | } |
295 | v = ul; // ullong divisions are expensive, avoid them | 296 | v = ul; // ullong divisions are expensive, avoid them |
296 | 297 | ||
297 | fmt = " 123456789"; | 298 | fmt = " 123456789"; |
298 | if (!idx) { // 9999 or less: use 1234 format | 299 | u = v / 10; |
299 | c = buf[0] = " 123456789"[v/10000]; | 300 | v = v % 10; |
301 | if (!idx) { | ||
302 | // 9999 or less: use "1234" format | ||
303 | // u is value/10, v is last digit | ||
304 | c = buf[0] = " 123456789"[u/100]; | ||
300 | if (c != ' ') fmt = "0123456789"; | 305 | if (c != ' ') fmt = "0123456789"; |
301 | c = buf[1] = fmt[v/1000%10]; | 306 | c = buf[1] = fmt[u/10%10]; |
302 | if (c != ' ') fmt = "0123456789"; | 307 | if (c != ' ') fmt = "0123456789"; |
303 | buf[2] = fmt[v/100%10]; | 308 | buf[2] = fmt[u%10]; |
304 | buf[3] = "0123456789"[v/10%10]; | 309 | buf[3] = "0123456789"[v]; |
305 | } else { | 310 | } else { |
306 | if (v >= 10*10) { // scaled value is >=10: use 123M format | 311 | // u is value, v is 1/10ths (allows for 9.2M format) |
307 | c = buf[0] = " 123456789"[v/1000]; | 312 | if (u >= 10) { |
313 | // value is >= 10: use "123M', " 12M" formats | ||
314 | c = buf[0] = " 123456789"[u/100]; | ||
308 | if (c != ' ') fmt = "0123456789"; | 315 | if (c != ' ') fmt = "0123456789"; |
309 | buf[1] = fmt[v/100%10]; | 316 | v = u % 10; |
310 | buf[2] = "0123456789"[v/10%10]; | 317 | u = u / 10; |
311 | } else { // scaled value is <10: use 1.2M format | 318 | buf[1] = fmt[u%10]; |
312 | buf[0] = "0123456789"[v/10]; | 319 | } else { |
320 | // value is < 10: use "9.2M" format | ||
321 | buf[0] = "0123456789"[u]; | ||
313 | buf[1] = '.'; | 322 | buf[1] = '.'; |
314 | buf[2] = "0123456789"[v%10]; | ||
315 | } | 323 | } |
324 | buf[2] = "0123456789"[v]; | ||
316 | // see http://en.wikipedia.org/wiki/Tera | 325 | // see http://en.wikipedia.org/wiki/Tera |
317 | buf[3] = " kMGTPEZY"[idx]; | 326 | buf[3] = " kMGTPEZY"[idx]; |
318 | } | 327 | } |
@@ -470,7 +479,8 @@ char *xasprintf(const char *format, ...) | |||
470 | va_end(p); | 479 | va_end(p); |
471 | #endif | 480 | #endif |
472 | 481 | ||
473 | if (r < 0) bb_error_msg_and_die(bb_msg_memory_exhausted); | 482 | if (r < 0) |
483 | bb_error_msg_and_die(bb_msg_memory_exhausted); | ||
474 | return string_ptr; | 484 | return string_ptr; |
475 | } | 485 | } |
476 | 486 | ||
diff --git a/procps/top.c b/procps/top.c index c02a959e0..abc7a4363 100644 --- a/procps/top.c +++ b/procps/top.c | |||
@@ -448,7 +448,7 @@ static void display_status(int count, int scr_width) | |||
448 | #endif | 448 | #endif |
449 | 449 | ||
450 | if (s->vsz >= 100*1024) | 450 | if (s->vsz >= 100*1024) |
451 | sprintf(vsz_str_buf, "%6ldM", s->vsz/1024); | 451 | sprintf(vsz_str_buf, "%6ldm", s->vsz/1024); |
452 | else | 452 | else |
453 | sprintf(vsz_str_buf, "%7ld", s->vsz); | 453 | sprintf(vsz_str_buf, "%7ld", s->vsz); |
454 | // PID PPID USER STAT VSZ %MEM [%CPU] COMMAND | 454 | // PID PPID USER STAT VSZ %MEM [%CPU] COMMAND |
@@ -519,23 +519,29 @@ int top_main(int argc, char **argv); | |||
519 | int top_main(int argc, char **argv) | 519 | int top_main(int argc, char **argv) |
520 | { | 520 | { |
521 | int count, lines, col; | 521 | int count, lines, col; |
522 | unsigned interval = 5; /* default update rate is 5 seconds */ | 522 | unsigned interval; |
523 | unsigned iterations = UINT_MAX; /* 2^32 iterations by default :) */ | 523 | int iterations = -1; /* infinite */ |
524 | char *sinterval, *siterations; | 524 | char *sinterval, *siterations; |
525 | #if ENABLE_FEATURE_USE_TERMIOS | 525 | #if ENABLE_FEATURE_USE_TERMIOS |
526 | struct termios new_settings; | 526 | struct termios new_settings; |
527 | struct timeval tv; | 527 | struct pollfd pfd[1]; |
528 | fd_set readfds; | ||
529 | unsigned char c; | 528 | unsigned char c; |
529 | |||
530 | pfd[0].fd = 0; | ||
531 | pfd[0].events = POLLIN; | ||
530 | #endif /* FEATURE_USE_TERMIOS */ | 532 | #endif /* FEATURE_USE_TERMIOS */ |
531 | 533 | ||
532 | interval = 5; | 534 | interval = 5; /* default update rate is 5 seconds */ |
533 | 535 | ||
534 | /* do normal option parsing */ | 536 | /* do normal option parsing */ |
535 | opt_complementary = "-"; | 537 | opt_complementary = "-"; |
536 | getopt32(argv, "d:n:b", &sinterval, &siterations); | 538 | getopt32(argv, "d:n:b", &sinterval, &siterations); |
537 | if (option_mask32 & 0x1) interval = xatou(sinterval); // -d | 539 | if (option_mask32 & 0x1) { |
538 | if (option_mask32 & 0x2) iterations = xatou(siterations); // -n | 540 | /* Need to limit it to not overflow poll timeout */ |
541 | interval = xatou16(sinterval); // -d | ||
542 | } | ||
543 | if (option_mask32 & 0x2) | ||
544 | iterations = xatoi_u(siterations); // -n | ||
539 | //if (option_mask32 & 0x4) // -b | 545 | //if (option_mask32 & 0x4) // -b |
540 | 546 | ||
541 | /* change to /proc */ | 547 | /* change to /proc */ |
@@ -584,9 +590,8 @@ int top_main(int argc, char **argv) | |||
584 | | PSSCAN_UTIME | 590 | | PSSCAN_UTIME |
585 | | PSSCAN_STATE | 591 | | PSSCAN_STATE |
586 | | PSSCAN_COMM | 592 | | PSSCAN_COMM |
587 | | PSSCAN_SID | ||
588 | | PSSCAN_UIDGID | 593 | | PSSCAN_UIDGID |
589 | ))) { | 594 | )) != NULL) { |
590 | int n = ntop; | 595 | int n = ntop; |
591 | top = xrealloc(top, (++ntop) * sizeof(*top)); | 596 | top = xrealloc(top, (++ntop) * sizeof(*top)); |
592 | top[n].pid = p->pid; | 597 | top[n].pid = p->pid; |
@@ -622,15 +627,9 @@ int top_main(int argc, char **argv) | |||
622 | /* show status for each of the processes */ | 627 | /* show status for each of the processes */ |
623 | display_status(count, col); | 628 | display_status(count, col); |
624 | #if ENABLE_FEATURE_USE_TERMIOS | 629 | #if ENABLE_FEATURE_USE_TERMIOS |
625 | tv.tv_sec = interval; | 630 | if (poll(pfd, 1, interval * 1000) != 0) { |
626 | tv.tv_usec = 0; | 631 | if (read(0, &c, 1) != 1) /* signal */ |
627 | FD_ZERO(&readfds); | 632 | break; |
628 | FD_SET(0, &readfds); | ||
629 | select(1, &readfds, NULL, NULL, &tv); | ||
630 | if (FD_ISSET(0, &readfds)) { | ||
631 | if (read(0, &c, 1) <= 0) { /* signal */ | ||
632 | return EXIT_FAILURE; | ||
633 | } | ||
634 | if (c == 'q' || c == initial_settings.c_cc[VINTR]) | 633 | if (c == 'q' || c == initial_settings.c_cc[VINTR]) |
635 | break; | 634 | break; |
636 | if (c == 'M') { | 635 | if (c == 'M') { |
@@ -662,7 +661,7 @@ int top_main(int argc, char **argv) | |||
662 | #endif | 661 | #endif |
663 | } | 662 | } |
664 | } | 663 | } |
665 | if (!--iterations) | 664 | if (iterations >= 0 && !--iterations) |
666 | break; | 665 | break; |
667 | #else | 666 | #else |
668 | sleep(interval); | 667 | sleep(interval); |