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