]> granicus.if.org Git - procps-ng/commitdiff
vmstat: validate numeric user input and allow infinte updates
authorSami Kerola <kerolasa@iki.fi>
Sun, 18 Dec 2011 13:55:30 +0000 (14:55 +0100)
committerSami Kerola <kerolasa@iki.fi>
Tue, 20 Dec 2011 16:30:54 +0000 (17:30 +0100)
The vmstat used ULONG_MAX as definition of infinite updates.  On a
computer with mighty uptime one will find that after 136 years
(assuming 1 second update interval) the vmstat exits, which is in
conflict with a promise of infinite.

Signed-off-by: Sami Kerola <kerolasa@iki.fi>
Makefile.am
vmstat.c

index c156a8cdd6dffa45cec0239a05c45e7bc3894a01..00e7d57e829218df449f2f541791f8b9ea3b80ec 100644 (file)
@@ -68,6 +68,7 @@ skill_SOURCES = skill.c $(top_srcdir)/lib/strutils.c
 snice_SOURCES = skill.c $(top_srcdir)/lib/strutils.c
 tload_SOURCES = tload.c $(top_srcdir)/lib/strutils.c
 pkill_SOURCES = pgrep.c
+vmstat_SOURCES = vmstat.c $(top_srcdir)/lib/strutils.c
 
 sysconf_DATA = sysctl.conf
 
index ee13563f5bbc860e9d764a74ba8c8c13cdb26f6e..fddffbc13541ae22fa41e4d7522c75d7519166ac 100644 (file)
--- a/vmstat.c
+++ b/vmstat.c
@@ -31,6 +31,7 @@
 
 #include "c.h"
 #include "nls.h"
+#include "strutils.h"
 #include "proc/sysinfo.h"
 #include "proc/version.h"
 
@@ -56,6 +57,7 @@ static int statMode = VMSTAT;
 static int a_option;
 
 static unsigned sleep_time = 1;
+static int infinite_updates = 0;
 static unsigned long num_updates;
 /* window height */
 static unsigned int height;
@@ -260,7 +262,7 @@ static void new_format(void)
        );
 
        /* main loop */
-       for (i = 1; i < num_updates; i++) {
+       for (i = 1; infinite_updates || i < num_updates; i++) {
                sleep(sleep_time);
                if (moreheaders && ((i % height) == 0))
                        new_header();
@@ -381,7 +383,7 @@ static int diskpartition_format(const char *partition_name)
        fflush(stdout);
        free(disks);
        free(partitions);
-       for (j = 1; j < num_updates; j++) {
+       for (j = 1; infinite_updates || j < num_updates; j++) {
                if (moreheaders && ((j % height) == 0))
                        diskpartition_header(partition_name);
                sleep(sleep_time);
@@ -474,7 +476,7 @@ static void diskformat(void)
                }
                free(disks);
                free(partitions);
-               for (j = 1; j < num_updates; j++) {
+               for (j = 1; infinite_updates || j < num_updates; j++) {
                        sleep(sleep_time);
                        ndisks = getdiskstat(&disks, &partitions);
                for (i = 0; i < ndisks; i++, k++) {
@@ -547,7 +549,7 @@ static void slabformat(void)
                       slabs[k].objsize, slabs[k].objperslab);
        }
        free(slabs);
-       for (j = 1, k = 1; j < num_updates; j++) {
+       for (j = 1, k = 1; infinite_updates || j < num_updates; j++) {
                sleep(sleep_time);
                nSlab = getslabinfo(&slabs);
                for (i = 0; i < nSlab; i++, k++) {
@@ -687,6 +689,7 @@ int main(int argc, char *argv[])
 {
        char *partition = NULL;
        int c;
+       long tmp;
 
        static const struct option longopts[] = {
                {"active", no_argument, NULL, 'a'},
@@ -777,12 +780,18 @@ int main(int argc, char *argv[])
                }
 
        if (optind < argc) {
-               if ((sleep_time = atoi(argv[optind++])) == 0)
-                       usage(stderr);
-               num_updates = ULONG_MAX;
+               tmp = strtol_or_err(argv[optind++], _("failed to parse argument"));
+               if (tmp < 1)
+                       errx(EXIT_FAILURE, _("delay must be positive integer"));
+               else if (UINT_MAX < tmp)
+                       errx(EXIT_FAILURE, _("too large delay value"));
+               sleep_time = tmp;
+               infinite_updates = 1;
+       }
+       if (optind < argc) {
+               num_updates = strtol_or_err(argv[optind++], _("failed to parse argument"));
+               infinite_updates = 0;
        }
-       if (optind < argc)
-               num_updates = atol(argv[optind++]);
        if (optind < argc)
                usage(stderr);