LTP uses `top -d 0.1`, which isn't convincingly useful, but general
support for other time units might be useful, and switching to xparsetime
addresses both at once.

Also fix 3169d948c049664bcf7216d4c4ae751881099d3e where I mistakenly
treated `rev` and `toys.optflags&FLAG_b` as interchangeable. (Without
this second fix, `top -b` looks fine but `top` is broken!)

Also fix xparsetime to reject input such as "monkey" or "1monkey".
---
 lib/xwrap.c     | 10 +++++++---
 tests/top.test  |  6 ++++++
 toys/posix/ps.c | 23 +++++++++++++++--------
 3 files changed, 28 insertions(+), 11 deletions(-)
From 35ad26f72cdc8c3483d4cbd14b79222a1dcc7cd1 Mon Sep 17 00:00:00 2001
From: Elliott Hughes <e...@google.com>
Date: Thu, 3 May 2018 15:09:14 -0700
Subject: [PATCH] Support fractional seconds (and other time units) in `top
 -d`.

LTP uses `top -d 0.1`, which isn't convincingly useful, but general
support for other time units might be useful, and switching to xparsetime
addresses both at once.

Also fix 3169d948c049664bcf7216d4c4ae751881099d3e where I mistakenly
treated `rev` and `toys.optflags&FLAG_b` as interchangeable. (Without
this second fix, `top -b` looks fine but `top` is broken!)

Also fix xparsetime to reject input such as "monkey" or "1monkey".
---
 lib/xwrap.c     | 10 +++++++---
 tests/top.test  |  6 ++++++
 toys/posix/ps.c | 23 +++++++++++++++--------
 3 files changed, 28 insertions(+), 11 deletions(-)

diff --git a/lib/xwrap.c b/lib/xwrap.c
index 54985db..26383c9 100644
--- a/lib/xwrap.c
+++ b/lib/xwrap.c
@@ -792,15 +792,19 @@ long xparsetime(char *arg, long units, long *fraction)
 {
   double d;
   long l;
+  char *end;
+
+  if (CFG_TOYBOX_FLOAT) d = strtod(arg, &end);
+  else l = strtoul(arg, &end, 10);
 
-  if (CFG_TOYBOX_FLOAT) d = strtod(arg, &arg);
-  else l = strtoul(arg, &arg, 10);
+  if (end == arg) error_exit("Not a number '%s'", arg);
+  arg = end;
 
   // Parse suffix
   if (*arg) {
     int ismhd[]={1,60,3600,86400}, i = stridx("smhd", *arg);
 
-    if (i == -1) error_exit("Unknown suffix '%c'", *arg);
+    if (i == -1 || *(arg+1)) error_exit("Unknown suffix '%s'", arg);
     if (CFG_TOYBOX_FLOAT) d *= ismhd[i];
     else l *= ismhd[i];
   }
diff --git a/tests/top.test b/tests/top.test
index 11eea33..3c3b597 100755
--- a/tests/top.test
+++ b/tests/top.test
@@ -5,3 +5,9 @@
 #testing "name" "command" "result" "infile" "stdin"
 
 testing "batch termination" "top -b -n1 | tail -c 1" "\n" "" ""
+testing "fractional seconds" "top -b -d 8.5 -n1 | tail -c 1" "\n" "" ""
+
+# These are unit tests of xparsetime.
+testing "-d invalid input" "top -b -d monkey -n1 2>&1 >/dev/null" "top: Not a number 'monkey'\n" "" ""
+testing "-d unknown suffix" "top -b -d 1u -n1 2>&1 >/dev/null" "top: Unknown suffix 'u'\n" "" ""
+testing "-d suffix trailing junk" "top -b -d 1monkey -n1 2>&1 >/dev/null" "top: Unknown suffix 'monkey'\n" "" ""
diff --git a/toys/posix/ps.c b/toys/posix/ps.c
index c5c0f79..c5d487f 100644
--- a/toys/posix/ps.c
+++ b/toys/posix/ps.c
@@ -48,8 +48,8 @@ USE_PS(NEWTOY(ps, "k(sort)*P(ppid)*aAdeflMno*O*p(pid)*s*t*Tu*U*g*G*wZ[!ol][+Ae][
 // stayroot because iotop needs root to read other process' proc/$$/io
 // TOP and IOTOP have a large common option block used for common processing,
 // the default values are different but the flags are in the same order.
-USE_TOP(NEWTOY(top, ">0O*" "Hk*o*p*u*s#<1d#=3<1m#n#<1bq[!oO]", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_LOCALE))
-USE_IOTOP(NEWTOY(iotop, ">0AaKO" "Hk*o*p*u*s#<1=7d#=3<1m#n#<1bq", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_STAYROOT|TOYFLAG_LOCALE))
+USE_TOP(NEWTOY(top, ">0O*" "Hk*o*p*u*s#<1d:m#n#<1bq[!oO]", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_LOCALE))
+USE_IOTOP(NEWTOY(iotop, ">0AaKO" "Hk*o*p*u*s#<1=7d:m#n#<1bq", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_STAYROOT|TOYFLAG_LOCALE))
 USE_PGREP(NEWTOY(pgrep, "?cld:u*U*t*s*P*g*G*fnovxL:[-no]", TOYFLAG_USR|TOYFLAG_BIN))
 USE_PKILL(NEWTOY(pkill,    "?Vu*U*t*s*P*g*G*fnovxl:[-no]", TOYFLAG_USR|TOYFLAG_BIN))
 
@@ -249,13 +249,15 @@ GLOBALS(
     struct {
       long n;
       long m;
-      long d;
+      char *d;
       long s;
       struct arg_list *u;
       struct arg_list *p;
       struct arg_list *o;
       struct arg_list *k;
       struct arg_list *O;
+
+      long d_ms;
     } top;
     struct {
       char *L;
@@ -1359,9 +1361,9 @@ static int header_line(int line, int rev)
 
   if (toys.optflags&FLAG_b) rev = 0;
 
-  printf("%s%*.*s%s\n", rev ? "\033[7m" : "",
+  printf("%s%*.*s%s%s\n", rev ? "\033[7m" : "",
     (toys.optflags&FLAG_b) ? 0 : -TT.width, TT.width, toybuf,
-    rev ? "\033[0m\r" : "");
+    rev ? "\033[0m" : "", (toys.optflags&FLAG_b) ? "" : "\r");
 
   return line-1;
 }
@@ -1566,8 +1568,8 @@ static void top_common(
       }
 
       now = millitime();
-      if (timeout<=now) timeout = new.whence+TT.top.d;
-      if (timeout<=now || timeout>now+TT.top.d) timeout = now+TT.top.d;
+      if (timeout<=now) timeout = new.whence+TT.top.d_ms;
+      if (timeout<=now || timeout>now+TT.top.d_ms) timeout = now+TT.top.d_ms;
 
       // In batch mode, we ignore the keyboard.
       if (toys.optflags&FLAG_b) {
@@ -1621,7 +1623,12 @@ static void top_common(
 
 static void top_setup(char *defo, char *defk)
 {
-  TT.top.d *= 1000;
+  if (TT.top.d) {
+    long frac;
+
+    TT.top.d_ms = xparsetime(TT.top.d, 1000, &frac) * 1000;
+    TT.top.d_ms += frac;
+  } else TT.top.d_ms = 3000;
 
   TT.ticks = sysconf(_SC_CLK_TCK); // units for starttime/uptime
   TT.tty = tty_fd() != -1;
-- 
2.17.0.441.gb46fe60e1d-goog

_______________________________________________
Toybox mailing list
Toybox@lists.landley.net
http://lists.landley.net/listinfo.cgi/toybox-landley.net

Reply via email to