summaryrefslogtreecommitdiff
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 89a1695..678c561 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -27,6 +27,7 @@
#include <stddef.h>
#include <string.h>
/* #include <strings.h> - said to be obsolete */
+#include <sys/poll.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/socket.h>
diff --git a/libbb/xfuncs.c b/libbb/xfuncs.c
index fa9fc10..140c7bb 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 c02a959..abc7a43 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);