=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/systat/main.c,v retrieving revision 1.72 retrieving revision 1.73 diff -c -r1.72 -r1.73 *** src/usr.bin/systat/main.c 2020/01/12 20:51:08 1.72 --- src/usr.bin/systat/main.c 2021/01/30 08:44:42 1.73 *************** *** 1,4 **** ! /* $OpenBSD: main.c,v 1.72 2020/01/12 20:51:08 martijn Exp $ */ /* * Copyright (c) 2001, 2007 Can Erkin Acar * Copyright (c) 2001 Daniel Hartmeier --- 1,4 ---- ! /* $OpenBSD: main.c,v 1.73 2021/01/30 08:44:42 martijn Exp $ */ /* * Copyright (c) 2001, 2007 Can Erkin Acar * Copyright (c) 2001 Daniel Hartmeier *************** *** 40,48 **** --- 40,50 ---- #include #include #include + #include #include #include #include + #include #include #include #include *************** *** 73,78 **** --- 75,81 ---- int ucount(void); void usage(void); + double strtodnum(const char *, double, double, const char **); /* command prompt */ *************** *** 323,331 **** cmd_delay(const char *buf) { double del; ! del = atof(buf); ! if (del > 0) { udelay = (useconds_t)(del * 1000000); gotsig_alarm = 1; naptime = del; --- 326,339 ---- cmd_delay(const char *buf) { double del; ! const char *errstr; ! 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,419 **** --- 422,469 ---- 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,427 **** const char *errstr; extern char *optarg; extern int optind; ! double delay = 5; char *viewstr = NULL; --- 471,477 ---- const char *errstr; extern char *optarg; extern int optind; ! double delay = 5, del; char *viewstr = NULL; *************** *** 475,483 **** nflag = 1; break; case 's': ! delay = atof(optarg); ! if (delay <= 0) ! delay = 5; break; case 'w': rawwidth = strtonum(optarg, 1, MAX_LINE_BUF-1, &errstr); --- 525,535 ---- nflag = 1; break; case 's': ! 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,512 **** argv += optind; if (argc == 1) { ! double del = atof(argv[0]); ! if (del == 0) viewstr = argv[0]; else delay = del; } else if (argc == 2) { viewstr = argv[0]; ! delay = atof(argv[1]); ! if (delay <= 0) ! delay = 5; } udelay = (useconds_t)(delay * 1000000.0); --- 549,564 ---- argv += optind; if (argc == 1) { ! 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 = 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);