*
* 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"
// totalswap=134209536, freeswap=134209536, procs=157})
#include "libbb.h"
+#include "common_bufsiz.h"
typedef unsigned long long ullong;
smallint is26;
// 1 if sample delay is not an integer fraction of a second
smallint need_seconds;
+ char final_char;
char *cur_outbuf;
- const char *final_str;
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!
#define is26 (G.is26 )
#define need_seconds (G.need_seconds )
#define cur_outbuf (G.cur_outbuf )
-#define final_str (G.final_str )
-#define delta (G.delta )
-#define deltanz (G.deltanz )
#define tv (G.tv )
#define proc_stat (G.proc_stat )
#define proc_loadavg (G.proc_loadavg )
#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; \
- final_str = "\n"; \
- deltanz = delta = 1000000; \
+ G.final_char = '\n'; \
+ 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;
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;
static void put_c(char c)
{
- if (cur_outbuf < outbuf + sizeof(outbuf))
+ if (cur_outbuf < outbuf + COMMON_BUFSIZE)
*cur_outbuf++ = c;
}
put(buf);
}
-
#define S_STAT(a) \
typedef struct a { \
struct s_stat *next; \
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)
{
- final_str = "\r";
- return (s_stat*)0;
+ G.final_char = '\r';
+ return NULL;
}
-
// user nice system idle iowait irq softirq (last 3 only in 2.6)
//cpu 649369 0 341297 4336769 11640 7122 1183
//cpuN 649369 0 341297 4336769 11640 7122 1183
S_STAT(cpu_stat)
ullong old[CPU_FIELDCNT];
int bar_sz;
- char *bar;
+ char bar[1];
S_STAT_END(cpu_stat)
-
static void FAST_FUNC collect_cpu(cpu_stat *s)
{
ullong data[CPU_FIELDCNT] = { 0, 0, 0, 0, 0, 0, 0 };
put(s->bar);
}
-
static s_stat* init_cpu(const char *param)
{
int sz;
- cpu_stat *s = xzalloc(sizeof(*s));
- s->collect = collect_cpu;
+ cpu_stat *s;
sz = strtoul(param, NULL, 0); /* param can be "" */
if (sz < 10) sz = 10;
if (sz > 1000) sz = 1000;
- s->bar = xzalloc(sz+1);
+ s = xzalloc(sizeof(*s) + sz);
/*s->bar[sz] = '\0'; - xzalloc did it */
s->bar_sz = sz;
+ s->collect = collect_cpu;
return (s_stat*)s;
}
-
S_STAT(int_stat)
ullong old;
int no;
return (s_stat*)s;
}
-
S_STAT(ctx_stat)
ullong old;
S_STAT_END(ctx_stat)
return (s_stat*)s;
}
-
S_STAT(blk_stat)
const char* lookfor;
ullong old[2];
return (s_stat*)s;
}
-
S_STAT(fork_stat)
ullong old;
S_STAT_END(fork_stat)
return (s_stat*)s;
}
-
S_STAT(if_stat)
ullong old[4];
const char *device;
return (s_stat*)s;
}
-
S_STAT(mem_stat)
char opt;
S_STAT_END(mem_stat)
return (s_stat*)s;
}
-
S_STAT(swp_stat)
S_STAT_END(swp_stat)
return (s_stat*)s;
}
-
S_STAT(fd_stat)
S_STAT_END(fd_stat)
return (s_stat*)s;
}
-
S_STAT(time_stat)
- int prec;
- int scale;
+ unsigned prec;
+ unsigned scale;
S_STAT_END(time_stat)
static void FAST_FUNC collect_time(time_stat *s)
{
char buf[sizeof("12:34:56.123456")];
struct tm* tm;
- int us = tv.tv_usec + s->scale/2;
+ unsigned us = tv.tv_usec + s->scale/2;
time_t t = tv.tv_sec;
if (us >= 1000000) {
}
}
-
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,
init_fork,
init_time,
init_blk,
- init_delay,
init_cr
};
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])
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;
}
}
// 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) {
gettimeofday(&tv, NULL);
collect_info(first);
- put(final_str);
+ put_c(G.final_char);
print_outbuf();
// Negative delta -> no usleep at all
// 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);
}