vmstat: validate numeric user input and allow infinte updates

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>
This commit is contained in:
Sami Kerola 2011-12-18 14:55:30 +01:00
parent 9047933b2d
commit 032f2ed674
2 changed files with 19 additions and 9 deletions

View File

@ -68,6 +68,7 @@ skill_SOURCES = skill.c $(top_srcdir)/lib/strutils.c
snice_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 tload_SOURCES = tload.c $(top_srcdir)/lib/strutils.c
pkill_SOURCES = pgrep.c pkill_SOURCES = pgrep.c
vmstat_SOURCES = vmstat.c $(top_srcdir)/lib/strutils.c
sysconf_DATA = sysctl.conf sysconf_DATA = sysctl.conf

View File

@ -31,6 +31,7 @@
#include "c.h" #include "c.h"
#include "nls.h" #include "nls.h"
#include "strutils.h"
#include "proc/sysinfo.h" #include "proc/sysinfo.h"
#include "proc/version.h" #include "proc/version.h"
@ -56,6 +57,7 @@ static int statMode = VMSTAT;
static int a_option; static int a_option;
static unsigned sleep_time = 1; static unsigned sleep_time = 1;
static int infinite_updates = 0;
static unsigned long num_updates; static unsigned long num_updates;
/* window height */ /* window height */
static unsigned int height; static unsigned int height;
@ -260,7 +262,7 @@ static void new_format(void)
); );
/* main loop */ /* main loop */
for (i = 1; i < num_updates; i++) { for (i = 1; infinite_updates || i < num_updates; i++) {
sleep(sleep_time); sleep(sleep_time);
if (moreheaders && ((i % height) == 0)) if (moreheaders && ((i % height) == 0))
new_header(); new_header();
@ -381,7 +383,7 @@ static int diskpartition_format(const char *partition_name)
fflush(stdout); fflush(stdout);
free(disks); free(disks);
free(partitions); free(partitions);
for (j = 1; j < num_updates; j++) { for (j = 1; infinite_updates || j < num_updates; j++) {
if (moreheaders && ((j % height) == 0)) if (moreheaders && ((j % height) == 0))
diskpartition_header(partition_name); diskpartition_header(partition_name);
sleep(sleep_time); sleep(sleep_time);
@ -474,7 +476,7 @@ static void diskformat(void)
} }
free(disks); free(disks);
free(partitions); free(partitions);
for (j = 1; j < num_updates; j++) { for (j = 1; infinite_updates || j < num_updates; j++) {
sleep(sleep_time); sleep(sleep_time);
ndisks = getdiskstat(&disks, &partitions); ndisks = getdiskstat(&disks, &partitions);
for (i = 0; i < ndisks; i++, k++) { for (i = 0; i < ndisks; i++, k++) {
@ -547,7 +549,7 @@ static void slabformat(void)
slabs[k].objsize, slabs[k].objperslab); slabs[k].objsize, slabs[k].objperslab);
} }
free(slabs); 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); sleep(sleep_time);
nSlab = getslabinfo(&slabs); nSlab = getslabinfo(&slabs);
for (i = 0; i < nSlab; i++, k++) { for (i = 0; i < nSlab; i++, k++) {
@ -687,6 +689,7 @@ int main(int argc, char *argv[])
{ {
char *partition = NULL; char *partition = NULL;
int c; int c;
long tmp;
static const struct option longopts[] = { static const struct option longopts[] = {
{"active", no_argument, NULL, 'a'}, {"active", no_argument, NULL, 'a'},
@ -777,12 +780,18 @@ int main(int argc, char *argv[])
} }
if (optind < argc) { if (optind < argc) {
if ((sleep_time = atoi(argv[optind++])) == 0) tmp = strtol_or_err(argv[optind++], _("failed to parse argument"));
usage(stderr); if (tmp < 1)
num_updates = ULONG_MAX; 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) if (optind < argc)
usage(stderr); usage(stderr);