On Tue, 2021-01-26 at 16:40 +0100, Alexander Bluhm wrote:
> On Mon, Jan 25, 2021 at 11:17:04AM +0100, Martijn van Duren wrote:
> >         if (argc == 1) {
> > -               double del = atof(argv[0]);
> > -               if (del == 0)
> > +               delay = strtodnum(argv[0], 0, UINT32_MAX / 1000000, 
> > &errstr);
> > +               if (errstr != NULL)
> >                         viewstr = argv[0];
> > -               else
> > -                       delay = del;
> 
> You need the else.  delay should only be changed if parsing was successful.
> 
> >         } else if (argc == 2) {
> >                 viewstr = argv[0];
> > -               delay = atof(argv[1]);
> > -               if (delay <= 0)
> > -                       delay = 5;
> > +               delay = strtodnum(optarg, 0, UINT32_MAX / 1000000, &errstr);
> 
> This should be argv[1] instead of optarg.
> 
> > +               if (errstr != NULL)
> > +                       errx(1, "-s \"%s\": delay value is %s", optarg, 
> > errstr);
> >         }
> 
> The -s in the error message is wrong.  Here delay was passed as argument.
> 
> bluhm
> 
Thanks for checking. Should be fixed below.

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);


Reply via email to