[prev in list] [next in list] [prev in thread] [next in thread]
List: openbsd-tech
Subject: Re: systat(1): improve parsing of delay value
From: Alexander Bluhm <alexander.bluhm () gmx ! net>
Date: 2021-01-28 21:51:01
Message-ID: YBMxxc2VunM+ghxZ () t430s ! bluhm ! invalid
[Download RAW message or body]
On Thu, Jan 28, 2021 at 09:06:51PM +0100, Martijn van Duren wrote:
> Thanks for checking. Should be fixed below.
OK bluhm@
> Index: main.c
> ===================================================================
> RCS file: /cvs/src/usr.bin/systat/main.c,v
> retrieving revision 1.72
> diff -u -p -r1.72 main.c
> --- main.c 12 Jan 2020 20:51:08 -0000 1.72
> +++ main.c 28 Jan 2021 20:05:30 -0000
> @@ -40,9 +40,11 @@
> #include <errno.h>
> #include <fcntl.h>
> #include <limits.h>
> +#include <math.h>
> #include <netdb.h>
> #include <signal.h>
> #include <stdio.h>
> +#include <stdint.h>
> #include <stdlib.h>
> #include <string.h>
> #include <stdarg.h>
> @@ -73,6 +75,7 @@ char uloadbuf[TIMEPOS];
>
> int ucount(void);
> void usage(void);
> +double strtodnum(const char *, double, double, const char **);
>
> /* command prompt */
>
> @@ -323,9 +326,14 @@ void
> cmd_delay(const char *buf)
> {
> double del;
> - del = atof(buf);
> + const char *errstr;
>
> - if (del > 0) {
> + if (buf[0] == '\0')
> + return;
> + del = strtodnum(buf, 0, UINT32_MAX / 1000000, &errstr);
> + if (errstr != NULL)
> + error("s: \"%s\": delay value is %s", buf, errstr);
> + else {
> udelay = (useconds_t)(del * 1000000);
> gotsig_alarm = 1;
> naptime = del;
> @@ -414,6 +422,48 @@ gethz(void)
> hz = cinf.hz;
> }
>
> +#define INVALID 1
> +#define TOOSMALL 2
> +#define TOOLARGE 3
> +
> +double
> +strtodnum(const char *nptr, double minval, double maxval, const char **errstrp)
> +{
> + double d = 0;
> + int error = 0;
> + char *ep;
> + struct errval {
> + const char *errstr;
> + int err;
> + } ev[4] = {
> + { NULL, 0 },
> + { "invalid", EINVAL },
> + { "too small", ERANGE },
> + { "too large", ERANGE },
> + };
> +
> + ev[0].err = errno;
> + errno = 0;
> + if (minval > maxval) {
> + error = INVALID;
> + } else {
> + d = strtod(nptr, &ep);
> + if (nptr == ep || *ep != '\0')
> + error = INVALID;
> + else if ((d == -HUGE_VAL && errno == ERANGE) || d < minval)
> + error = TOOSMALL;
> + else if ((d == HUGE_VAL && errno == ERANGE) || d > maxval)
> + error = TOOLARGE;
> + }
> + if (errstrp != NULL)
> + *errstrp = ev[error].errstr;
> + errno = ev[error].err;
> + if (error)
> + d = 0;
> +
> + return (d);
> +}
> +
> int
> main(int argc, char *argv[])
> {
> @@ -421,7 +471,7 @@ main(int argc, char *argv[])
> const char *errstr;
> extern char *optarg;
> extern int optind;
> - double delay = 5;
> + double delay = 5, del;
>
> char *viewstr = NULL;
>
> @@ -475,9 +525,11 @@ main(int argc, char *argv[])
> nflag = 1;
> break;
> case 's':
> - delay = atof(optarg);
> - if (delay <= 0)
> - delay = 5;
> + delay = strtodnum(optarg, 0, UINT32_MAX / 1000000,
> + &errstr);
> + if (errstr != NULL)
> + errx(1, "-s \"%s\": delay value is %s", optarg,
> + errstr);
> break;
> case 'w':
> rawwidth = strtonum(optarg, 1, MAX_LINE_BUF-1, &errstr);
> @@ -497,16 +549,16 @@ main(int argc, char *argv[])
> argv += optind;
>
> if (argc == 1) {
> - double del = atof(argv[0]);
> - if (del == 0)
> + del = strtodnum(argv[0], 0, UINT32_MAX / 1000000, &errstr);
> + if (errstr != NULL)
> viewstr = argv[0];
> else
> delay = del;
> } else if (argc == 2) {
> viewstr = argv[0];
> - delay = atof(argv[1]);
> - if (delay <= 0)
> - delay = 5;
> + delay = strtodnum(argv[1], 0, UINT32_MAX / 1000000, &errstr);
> + if (errstr != NULL)
> + errx(1, "\"%s\": delay value is %s", argv[1], errstr);
> }
>
> udelay = (useconds_t)(delay * 1000000.0);
>
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic