aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/libbb.h1
-rw-r--r--libbb/xfuncs.c46
-rw-r--r--procps/top.c39
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);
519int top_main(int argc, char **argv) 519int 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);