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 @@ #include #include /* #include - said to be obsolete */ +#include #include #include #include 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]) { const char *fmt; char c; - unsigned v,idx = 0; - ul *= 10; - if (ul > 9999*10) { // do not scale if 9999 or less - while (ul >= 10000) { + unsigned v, u, idx = 0; + + if (ul > 9999) { // do not scale if 9999 or less + ul *= 10; + do { ul /= 1024; idx++; - } + } while (ul >= 10000); } v = ul; // ullong divisions are expensive, avoid them fmt = " 123456789"; - if (!idx) { // 9999 or less: use 1234 format - c = buf[0] = " 123456789"[v/10000]; + u = v / 10; + v = v % 10; + if (!idx) { + // 9999 or less: use "1234" format + // u is value/10, v is last digit + c = buf[0] = " 123456789"[u/100]; if (c != ' ') fmt = "0123456789"; - c = buf[1] = fmt[v/1000%10]; + c = buf[1] = fmt[u/10%10]; if (c != ' ') fmt = "0123456789"; - buf[2] = fmt[v/100%10]; - buf[3] = "0123456789"[v/10%10]; + buf[2] = fmt[u%10]; + buf[3] = "0123456789"[v]; } else { - if (v >= 10*10) { // scaled value is >=10: use 123M format - c = buf[0] = " 123456789"[v/1000]; + // u is value, v is 1/10ths (allows for 9.2M format) + if (u >= 10) { + // value is >= 10: use "123M', " 12M" formats + c = buf[0] = " 123456789"[u/100]; if (c != ' ') fmt = "0123456789"; - buf[1] = fmt[v/100%10]; - buf[2] = "0123456789"[v/10%10]; - } else { // scaled value is <10: use 1.2M format - buf[0] = "0123456789"[v/10]; + v = u % 10; + u = u / 10; + buf[1] = fmt[u%10]; + } else { + // value is < 10: use "9.2M" format + buf[0] = "0123456789"[u]; buf[1] = '.'; - buf[2] = "0123456789"[v%10]; } + buf[2] = "0123456789"[v]; // see http://en.wikipedia.org/wiki/Tera buf[3] = " kMGTPEZY"[idx]; } @@ -470,7 +479,8 @@ char *xasprintf(const char *format, ...) va_end(p); #endif - if (r < 0) bb_error_msg_and_die(bb_msg_memory_exhausted); + if (r < 0) + bb_error_msg_and_die(bb_msg_memory_exhausted); return string_ptr; } 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) #endif if (s->vsz >= 100*1024) - sprintf(vsz_str_buf, "%6ldM", s->vsz/1024); + sprintf(vsz_str_buf, "%6ldm", s->vsz/1024); else sprintf(vsz_str_buf, "%7ld", s->vsz); // PID PPID USER STAT VSZ %MEM [%CPU] COMMAND @@ -519,23 +519,29 @@ int top_main(int argc, char **argv); int top_main(int argc, char **argv) { int count, lines, col; - unsigned interval = 5; /* default update rate is 5 seconds */ - unsigned iterations = UINT_MAX; /* 2^32 iterations by default :) */ + unsigned interval; + int iterations = -1; /* infinite */ char *sinterval, *siterations; #if ENABLE_FEATURE_USE_TERMIOS struct termios new_settings; - struct timeval tv; - fd_set readfds; + struct pollfd pfd[1]; unsigned char c; + + pfd[0].fd = 0; + pfd[0].events = POLLIN; #endif /* FEATURE_USE_TERMIOS */ - interval = 5; + interval = 5; /* default update rate is 5 seconds */ /* do normal option parsing */ opt_complementary = "-"; getopt32(argv, "d:n:b", &sinterval, &siterations); - if (option_mask32 & 0x1) interval = xatou(sinterval); // -d - if (option_mask32 & 0x2) iterations = xatou(siterations); // -n + if (option_mask32 & 0x1) { + /* Need to limit it to not overflow poll timeout */ + interval = xatou16(sinterval); // -d + } + if (option_mask32 & 0x2) + iterations = xatoi_u(siterations); // -n //if (option_mask32 & 0x4) // -b /* change to /proc */ @@ -584,9 +590,8 @@ int top_main(int argc, char **argv) | PSSCAN_UTIME | PSSCAN_STATE | PSSCAN_COMM - | PSSCAN_SID | PSSCAN_UIDGID - ))) { + )) != NULL) { int n = ntop; top = xrealloc(top, (++ntop) * sizeof(*top)); top[n].pid = p->pid; @@ -622,15 +627,9 @@ int top_main(int argc, char **argv) /* show status for each of the processes */ display_status(count, col); #if ENABLE_FEATURE_USE_TERMIOS - tv.tv_sec = interval; - tv.tv_usec = 0; - FD_ZERO(&readfds); - FD_SET(0, &readfds); - select(1, &readfds, NULL, NULL, &tv); - if (FD_ISSET(0, &readfds)) { - if (read(0, &c, 1) <= 0) { /* signal */ - return EXIT_FAILURE; - } + if (poll(pfd, 1, interval * 1000) != 0) { + if (read(0, &c, 1) != 1) /* signal */ + break; if (c == 'q' || c == initial_settings.c_cc[VINTR]) break; if (c == 'M') { @@ -662,7 +661,7 @@ int top_main(int argc, char **argv) #endif } } - if (!--iterations) + if (iterations >= 0 && !--iterations) break; #else sleep(interval);