ash: in tryexec(), ensure we don't try to run embedded scripts as applets
[oweals/busybox.git] / procps / nmeter.c
index 1cc908504daaf26c1e802b8ccc413b50e8d7fb54..166c8ab18e9c597932b82868ebbb6d46b6d07e87 100644 (file)
@@ -5,12 +5,11 @@
  *
  * Contact me: vda.linux@googlemail.com
  */
-
 //config:config NMETER
-//config:      bool "nmeter"
+//config:      bool "nmeter (10 kb)"
 //config:      default y
 //config:      help
-//config:        Prints selected system stats continuously, one line per update.
+//config:      Prints selected system stats continuously, one line per update.
 
 //applet:IF_NMETER(APPLET(nmeter, BB_DIR_USR_BIN, BB_SUID_DROP))
 
 //usage:#define nmeter_full_usage "\n\n"
 //usage:       "Monitor system in real time"
 //usage:     "\n"
-//usage:     "\n -d MSEC       Milliseconds between updates (default:1000)"
+//usage:     "\n -d MSEC       Milliseconds between updates, default:1000, none:-1"
 //usage:     "\n"
 //usage:     "\nFormat specifiers:"
-//usage:     "\n %Nc or %[cN]  CPU. N - bar size (default:10)"
+//usage:     "\n %Nc or %[cN]  CPU. N - bar size (default 10)"
 //usage:     "\n               (displays: S:system U:user N:niced D:iowait I:irq i:softirq)"
 //usage:     "\n %[nINTERFACE] Network INTERFACE"
 //usage:     "\n %m            Allocated memory"
@@ -53,6 +52,7 @@
 //  totalswap=134209536, freeswap=134209536, procs=157})
 
 #include "libbb.h"
+#include "common_bufsiz.h"
 
 typedef unsigned long long ullong;
 
@@ -86,7 +86,7 @@ struct globals {
        char final_char;
        char *cur_outbuf;
        int delta;
-       int deltanz;
+       unsigned deltanz;
        struct timeval tv;
 #define first_proc_file proc_stat
        proc_file proc_stat;    // Must match the order of proc_name's!
@@ -101,8 +101,6 @@ struct globals {
 #define is26               (G.is26              )
 #define need_seconds       (G.need_seconds      )
 #define cur_outbuf         (G.cur_outbuf        )
-#define delta              (G.delta             )
-#define deltanz            (G.deltanz           )
 #define tv                 (G.tv                )
 #define proc_stat          (G.proc_stat         )
 #define proc_loadavg       (G.proc_loadavg      )
@@ -110,16 +108,15 @@ struct globals {
 #define proc_meminfo       (G.proc_meminfo      )
 #define proc_diskstats     (G.proc_diskstats    )
 #define proc_sys_fs_filenr (G.proc_sys_fs_filenr)
+#define outbuf bb_common_bufsiz1
 #define INIT_G() do { \
+       setup_common_bufsiz(); \
        SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \
        cur_outbuf = outbuf; \
        G.final_char = '\n'; \
-       deltanz = delta = 1000000; \
+       G.deltanz = G.delta = 1000000; \
 } while (0)
 
-// We depend on this being a char[], not char* - we take sizeof() of it
-#define outbuf bb_common_bufsiz1
-
 static inline void reset_outbuf(void)
 {
        cur_outbuf = outbuf;
@@ -142,7 +139,7 @@ static void print_outbuf(void)
 static void put(const char *s)
 {
        char *p = cur_outbuf;
-       int sz = outbuf + sizeof(outbuf) - p;
+       int sz = outbuf + COMMON_BUFSIZE - p;
        while (*s && --sz >= 0)
                *p++ = *s++;
        cur_outbuf = p;
@@ -150,7 +147,7 @@ static void put(const char *s)
 
 static void put_c(char c)
 {
-       if (cur_outbuf < outbuf + sizeof(outbuf))
+       if (cur_outbuf < outbuf + COMMON_BUFSIZE)
                *cur_outbuf++ = c;
 }
 
@@ -342,14 +339,6 @@ static s_stat* init_literal(void)
        return (s_stat*)s;
 }
 
-static s_stat* init_delay(const char *param)
-{
-       delta = strtoul(param, NULL, 0) * 1000; /* param can be "" */
-       deltanz = delta > 0 ? delta : 1;
-       need_seconds = (1000000%deltanz) != 0;
-       return NULL;
-}
-
 static s_stat* init_cr(const char *param UNUSED_PARAM)
 {
        G.final_char = '\r';
@@ -817,8 +806,7 @@ static void FAST_FUNC collect_info(s_stat *s)
 
 typedef s_stat* init_func(const char *param);
 
-// Deprecated %NNNd is to be removed, -d MSEC supersedes it
-static const char options[] ALIGN1 = "ncmsfixptbdr";
+static const char options[] ALIGN1 = "ncmsfixptbr";
 static init_func *const init_functions[] = {
        init_if,
        init_cpu,
@@ -830,7 +818,6 @@ static init_func *const init_functions[] = {
        init_fork,
        init_time,
        init_blk,
-       init_delay,
        init_cr
 };
 
@@ -853,8 +840,11 @@ int nmeter_main(int argc UNUSED_PARAM, char **argv)
                is26 = (strstr(buf, " 2.4.") == NULL);
        }
 
-       if (getopt32(argv, "d:", &opt_d))
-               init_delay(opt_d);
+       if (getopt32(argv, "d:", &opt_d)) {
+               G.delta = xatoi(opt_d) * 1000;
+               G.deltanz = G.delta > 0 ? G.delta : 1;
+               need_seconds = (1000000 % G.deltanz) != 0;
+       }
        argv += optind;
 
        if (!argv[0])
@@ -909,8 +899,8 @@ int nmeter_main(int argc UNUSED_PARAM, char **argv)
                                last->next = s;
                        last = s;
                } else {
-                       // %NNNNd or %r option. remove it from string
-                       strcpy(prev + strlen(prev), cur);
+                       // %r option. remove it from string
+                       overlapping_strcpy(prev + strlen(prev), cur);
                        cur = prev;
                }
        }
@@ -928,9 +918,9 @@ int nmeter_main(int argc UNUSED_PARAM, char **argv)
        // Generate first samples but do not print them, they're bogus
        collect_info(first);
        reset_outbuf();
-       if (delta >= 0) {
+       if (G.delta >= 0) {
                gettimeofday(&tv, NULL);
-               usleep(delta > 1000000 ? 1000000 : delta - tv.tv_usec%deltanz);
+               usleep(G.delta > 1000000 ? 1000000 : G.delta - tv.tv_usec % G.deltanz);
        }
 
        while (1) {
@@ -944,18 +934,18 @@ int nmeter_main(int argc UNUSED_PARAM, char **argv)
                // time resolution ;)
                // TODO: detect and avoid useless updates
                // (like: nothing happens except time)
-               if (delta >= 0) {
+               if (G.delta >= 0) {
                        int rem;
                        // can be commented out, will sacrifice sleep time precision a bit
                        gettimeofday(&tv, NULL);
                        if (need_seconds)
-                               rem = delta - ((ullong)tv.tv_sec*1000000 + tv.tv_usec) % deltanz;
+                               rem = G.delta - ((ullong)tv.tv_sec*1000000 + tv.tv_usec) % G.deltanz;
                        else
-                               rem = delta - tv.tv_usec%deltanz;
+                               rem = G.delta - (unsigned)tv.tv_usec % G.deltanz;
                        // Sometimes kernel wakes us up just a tiny bit earlier than asked
                        // Do not go to very short sleep in this case
-                       if (rem < delta/128) {
-                               rem += delta;
+                       if (rem < (unsigned)G.delta / 128) {
+                               rem += G.delta;
                        }
                        usleep(rem);
                }