mass renaming Kbuild -> Kbuild.src, Config.in -> Config.src
[oweals/busybox.git] / procps / nmeter.c
index cded67e562868643a4757d43ea29cbfeb9f43e07..bb1e819a6fb77d49b2e800fd079afad862e20423 100644 (file)
 //  totalram=2107416576, freeram=211525632, sharedram=0, bufferram=157204480}
 //  totalswap=134209536, freeswap=134209536, procs=157})
 
-#include <time.h>
 #include "libbb.h"
 
 typedef unsigned long long ullong;
 
-enum { PROC_FILE_SIZE = 4096 };
+enum {  /* Preferably use powers of 2 */
+       PROC_MIN_FILE_SIZE = 256,
+       PROC_MAX_FILE_SIZE = 16 * 1024,
+};
 
 typedef struct proc_file {
        char *file;
-       //const char *name;
+       int file_sz;
        smallint last_gen;
 } proc_file;
 
@@ -124,30 +126,42 @@ static void put_question_marks(int count)
                put_c('?');
 }
 
-static void readfile_z(char *buf, int sz, const char* fname)
+static void readfile_z(proc_file *pf, const char* fname)
 {
 // open_read_close() will do two reads in order to be sure we are at EOF,
 // and we don't need/want that.
-//     sz = open_read_close(fname, buf, sz-1);
-
-       int fd = xopen(fname, O_RDONLY);
+       int fd;
+       int sz, rdsz;
+       char *buf;
+
+       sz = pf->file_sz;
+       buf = pf->file;
+       if (!buf) {
+               buf = xmalloc(PROC_MIN_FILE_SIZE);
+               sz = PROC_MIN_FILE_SIZE;
+       }
+ again:
+       fd = xopen(fname, O_RDONLY);
        buf[0] = '\0';
-       sz = read(fd, buf, sz - 1);
-       if (sz > 0)
-               buf[sz] = '\0';
+       rdsz = read(fd, buf, sz-1);
        close(fd);
+       if (rdsz > 0) {
+               if (rdsz == sz-1 && sz < PROC_MAX_FILE_SIZE) {
+                       sz *= 2;
+                       buf = xrealloc(buf, sz);
+                       goto again;
+               }
+               buf[rdsz] = '\0';
+       }
+       pf->file_sz = sz;
+       pf->file = buf;
 }
 
 static const char* get_file(proc_file *pf)
 {
        if (pf->last_gen != gen) {
                pf->last_gen = gen;
-               // We allocate PROC_FILE_SIZE bytes. This wastes memory,
-               // but allows us to allocate only once (at first sample)
-               // per proc file, and reuse buffer for each sample
-               if (!pf->file)
-                       pf->file = xmalloc(PROC_FILE_SIZE);
-               readfile_z(pf->file, PROC_FILE_SIZE, proc_name[pf - &first_proc_file]);
+               readfile_z(pf, proc_name[pf - &first_proc_file]);
        }
        return pf->file;
 }
@@ -267,14 +281,14 @@ static void scale(ullong ul)
 #define S_STAT(a) \
 typedef struct a { \
        struct s_stat *next; \
-       void (*collect)(struct a *s); \
+       void (*collect)(struct a *s) FAST_FUNC; \
        const char *label;
 #define S_STAT_END(a) } a;
 
 S_STAT(s_stat)
 S_STAT_END(s_stat)
 
-static void collect_literal(s_stat *s UNUSED_PARAM)
+static void FAST_FUNC collect_literal(s_stat *s UNUSED_PARAM)
 {
 }
 
@@ -311,7 +325,7 @@ S_STAT(cpu_stat)
 S_STAT_END(cpu_stat)
 
 
-static void collect_cpu(cpu_stat *s)
+static void FAST_FUNC collect_cpu(cpu_stat *s)
 {
        ullong data[CPU_FIELDCNT] = { 0, 0, 0, 0, 0, 0, 0 };
        unsigned frac[CPU_FIELDCNT] = { 0, 0, 0, 0, 0, 0, 0 };
@@ -385,7 +399,7 @@ S_STAT(int_stat)
        int no;
 S_STAT_END(int_stat)
 
-static void collect_int(int_stat *s)
+static void FAST_FUNC collect_int(int_stat *s)
 {
        ullong data[1];
        ullong old;
@@ -419,7 +433,7 @@ S_STAT(ctx_stat)
        ullong old;
 S_STAT_END(ctx_stat)
 
-static void collect_ctx(ctx_stat *s)
+static void FAST_FUNC collect_ctx(ctx_stat *s)
 {
        ullong data[1];
        ullong old;
@@ -448,7 +462,7 @@ S_STAT(blk_stat)
        ullong old[2];
 S_STAT_END(blk_stat)
 
-static void collect_blk(blk_stat *s)
+static void FAST_FUNC collect_blk(blk_stat *s)
 {
        ullong data[2];
        int i;
@@ -490,7 +504,7 @@ S_STAT(fork_stat)
        ullong old;
 S_STAT_END(fork_stat)
 
-static void collect_thread_nr(fork_stat *s UNUSED_PARAM)
+static void FAST_FUNC collect_thread_nr(fork_stat *s UNUSED_PARAM)
 {
        ullong data[1];
 
@@ -501,7 +515,7 @@ static void collect_thread_nr(fork_stat *s UNUSED_PARAM)
        scale(data[0]);
 }
 
-static void collect_fork(fork_stat *s)
+static void FAST_FUNC collect_fork(fork_stat *s)
 {
        ullong data[1];
        ullong old;
@@ -535,7 +549,7 @@ S_STAT(if_stat)
        char *device_colon;
 S_STAT_END(if_stat)
 
-static void collect_if(if_stat *s)
+static void FAST_FUNC collect_if(if_stat *s)
 {
        ullong data[4];
        int i;
@@ -610,7 +624,7 @@ S_STAT_END(mem_stat)
 //HugePages_Total:     0
 //HugePages_Free:      0
 //Hugepagesize:     4096 kB
-static void collect_mem(mem_stat *s)
+static void FAST_FUNC collect_mem(mem_stat *s)
 {
        ullong m_total = 0;
        ullong m_free = 0;
@@ -657,7 +671,7 @@ static s_stat* init_mem(const char *param)
 S_STAT(swp_stat)
 S_STAT_END(swp_stat)
 
-static void collect_swp(swp_stat *s UNUSED_PARAM)
+static void FAST_FUNC collect_swp(swp_stat *s UNUSED_PARAM)
 {
        ullong s_total[1];
        ullong s_free[1];
@@ -681,7 +695,7 @@ static s_stat* init_swp(const char *param UNUSED_PARAM)
 S_STAT(fd_stat)
 S_STAT_END(fd_stat)
 
-static void collect_fd(fd_stat *s UNUSED_PARAM)
+static void FAST_FUNC collect_fd(fd_stat *s UNUSED_PARAM)
 {
        ullong data[2];
 
@@ -706,7 +720,7 @@ S_STAT(time_stat)
        int scale;
 S_STAT_END(time_stat)
 
-static void collect_time(time_stat *s)
+static void FAST_FUNC collect_time(time_stat *s)
 {
        char buf[sizeof("12:34:56.123456")];
        struct tm* tm;
@@ -741,7 +755,7 @@ static s_stat* init_time(const char *param)
        return (s_stat*)s;
 }
 
-static void collect_info(s_stat *s)
+static void FAST_FUNC collect_info(s_stat *s)
 {
        gen ^= 1;
        while (s) {
@@ -771,7 +785,7 @@ static init_func *const init_functions[] = {
 };
 
 int nmeter_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
-int nmeter_main(int argc, char **argv)
+int nmeter_main(int argc UNUSED_PARAM, char **argv)
 {
        char buf[32];
        s_stat *first = NULL;
@@ -783,7 +797,7 @@ int nmeter_main(int argc, char **argv)
 
        xchdir("/proc");
 
-       if (argc != 2)
+       if (!argv[1])
                bb_show_usage();
 
        if (open_read_close("version", buf, sizeof(buf)-1) > 0) {