Re: [patch] have rtprio check that arguments are numeric; change atoi to strtol

2011-01-04 Thread Giorgos Keramidas
On Sun, 2 Jan 2011 18:46:47 -0500, Eitan Adler  wrote:
> What about this patch? I incorporated  your feedback so I am not going
> to reply inline.

Since the pattern of converting strings to int-derivative values appears
multiple times, I'd probably prefer something like a new function that
does the parsing *and* error-checking, to avoid duplication of errno
checks, invalidchar checks, and so on, e.g. something like this near the
top of rtprio.c:

#include 
#include 
#include 

/*
 * Parse an integer from 'string' into 'value'.  Return the first
 * invalid character in 'endp', if endp is non-NULL.  The return value
 * of parseint is 0 on success, -1 for any parse error.
 */

int
parseint(const char *string, const char **endp, int base, int *value)
{
long x;

errno = 0;
x = strtol(string, endp, base);
if (errno != 0 || endp == str || (endp != NULL &&
endp != str && *endp != '\0' && (isdigit(*endp) == 0 ||
isspace(*endp) != 0)))
return -1;
if (x >= INT_MAX) {
errno = ERANGE;
return -1;
}
return (int)x;
}

Then you can replace all the atoi() calls with:

int x;

if (parseint(argv[1], NULL, 0, &x) != 0)
errx(1, "your message");

which is a relatively cleaner way of handling strtol() parsing errors,
without the associated clutter of checking properly all possible edge
cases at every call-point.

___
freebsd-hackers@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-hackers
To unsubscribe, send any mail to "freebsd-hackers-unsubscr...@freebsd.org"


Re: [patch] have rtprio check that arguments are numeric; change atoi to strtol

2011-01-04 Thread Giorgos Keramidas
On Tue, 04 Jan 2011 11:36:38 +0100, Giorgos Keramidas  
wrote:
> On Sun, 2 Jan 2011 18:46:47 -0500, Eitan Adler  wrote:
>> What about this patch? I incorporated  your feedback so I am not going
>> to reply inline.
>
> Since the pattern of converting strings to int-derivative values appears
> multiple times, I'd probably prefer something like a new function that
> does the parsing *and* error-checking, to avoid duplication of errno
> checks, invalidchar checks, and so on, e.g. something like this near the
> top of rtprio.c:
>
> #include 
> #include 
> #include 
>
> /*
>  * Parse an integer from 'string' into 'value'.  Return the first
>  * invalid character in 'endp', if endp is non-NULL.  The return value
>  * of parseint is 0 on success, -1 for any parse error.
>  */
>
> int
> parseint(const char *string, const char **endp, int base, int *value)
> {
> long x;
>
> errno = 0;
> x = strtol(string, endp, base);
> if (errno != 0 || endp == str || (endp != NULL &&
> endp != str && *endp != '\0' && (isdigit(*endp) == 0 ||
> isspace(*endp) != 0)))
> return -1;
> if (x >= INT_MAX) {
> errno = ERANGE;
> return -1;
> }
> return (int)x;
> }

instead of `return (int)x' the last bits should be slightly different,
of course:

  if (value != NULL)
  *value = (int)x;
  return 0;
  }

___
freebsd-hackers@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-hackers
To unsubscribe, send any mail to "freebsd-hackers-unsubscr...@freebsd.org"


Re: [patch] have rtprio check that arguments are numeric; change atoi to strtol

2011-01-04 Thread Kostik Belousov
On Tue, Jan 04, 2011 at 11:40:45AM +0100, Giorgos Keramidas wrote:
> On Tue, 04 Jan 2011 11:36:38 +0100, Giorgos Keramidas  
> wrote:
> > On Sun, 2 Jan 2011 18:46:47 -0500, Eitan Adler  wrote:
> >> What about this patch? I incorporated  your feedback so I am not going
> >> to reply inline.
> >
> > Since the pattern of converting strings to int-derivative values appears
> > multiple times, I'd probably prefer something like a new function that
> > does the parsing *and* error-checking, to avoid duplication of errno
> > checks, invalidchar checks, and so on, e.g. something like this near the
> > top of rtprio.c:
> >
> > #include 
> > #include 
> > #include 
> >
> > /*
> >  * Parse an integer from 'string' into 'value'.  Return the first
> >  * invalid character in 'endp', if endp is non-NULL.  The return 
> > value
> >  * of parseint is 0 on success, -1 for any parse error.
> >  */
> >
> > int
> > parseint(const char *string, const char **endp, int base, int 
> > *value)
> > {
> > long x;
> >
> > errno = 0;
> > x = strtol(string, endp, base);
> > if (errno != 0 || endp == str || (endp != NULL &&
> > endp != str && *endp != '\0' && (isdigit(*endp) == 0 ||
> > isspace(*endp) != 0)))
> > return -1;
> > if (x >= INT_MAX) {
> > errno = ERANGE;
> > return -1;
> > }
> > return (int)x;
> > }
> 
> instead of `return (int)x' the last bits should be slightly different,
> of course:
> 
>   if (value != NULL)
>   *value = (int)x;
>   return 0;
>   }
Well, I think it shall be simplified. What about this ?

diff --git a/usr.sbin/rtprio/rtprio.c b/usr.sbin/rtprio/rtprio.c
index 245f714..fc212b5 100644
--- a/usr.sbin/rtprio/rtprio.c
+++ b/usr.sbin/rtprio/rtprio.c
@@ -37,31 +37,31 @@ __FBSDID("$FreeBSD$");
 
 #include 
 #include 
-#include 
 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
 #include 
 
-static void usage();
+static int parseint(const char *, const char *);
+static void usage(void);
 
 int
-main(argc, argv)
-   int argc;
-   char  **argv;
+main(int argc, char *argv[])
 {
-   char   *p;
-   int proc = 0;
struct rtprio rtp;
+   char *p;
+   pid_t proc;
 
/* find basename */
if ((p = rindex(argv[0], '/')) == NULL)
p = argv[0];
else
++p;
+   proc = 0;
 
if (!strcmp(p, "rtprio"))
rtp.type = RTP_PRIO_REALTIME;
@@ -70,12 +70,12 @@ main(argc, argv)
 
switch (argc) {
case 2:
-   proc = abs(atoi(argv[1]));  /* Should check if numeric
-* arg! */
+   proc = parseint(argv[1], "pid");
+   proc = abs(proc);
/* FALLTHROUGH */
case 1:
if (rtprio(RTP_LOOKUP, proc, &rtp) != 0)
-   err(1, "%s", argv[0]);
+   err(1, "RTP_LOOKUP");
printf("%s: ", p);
switch (rtp.type) {
case RTP_PRIO_REALTIME:
@@ -103,19 +103,17 @@ main(argc, argv)
usage();
break;
}
-   } else {
-   rtp.prio = atoi(argv[1]);
-   }
+   } else
+   rtp.prio = parseint(argv[1], "priority");
} else {
usage();
break;
}
 
if (argv[2][0] == '-')
-   proc = -atoi(argv[2]);
-
+   proc = parseint(argv[2] + 1, "pid");
if (rtprio(RTP_SET, proc, &rtp) != 0)
-   err(1, "%s", argv[0]);
+   err(1, "RTP_SET");
 
if (proc == 0) {
execvp(argv[2], &argv[2]);
@@ -123,12 +121,28 @@ main(argc, argv)
}
exit(0);
}
-   exit (1);
+   exit(1);
+}
+
+static int
+parseint(const char *str, const char *errname)
+{
+   char *endp;
+   long res;
+
+   errno = 0;
+   res = strtol(str, &endp, 10);
+   if (errno != 0 || endp == str || *endp != '\0')
+   err(1, "%s shall be a number", errname);
+   if (res >= INT_MAX)
+   err(1, "Integer overflow parsing %s", errname);
+   return (res);
 }
 
 static void
-usage()
+usage(void)
 {
+
(void) fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n%s\n",
"usage: [id|rt]prio",
"   [id|rt]prio [-]pid",


pgpRlkNXRGHNm.pgp
Description: PGP sign

Re: [patch] have rtprio check that arguments are numeric; change atoi to strtol

2011-01-04 Thread Giorgos Keramidas
On Tue, 4 Jan 2011 13:25:02 +0200, Kostik Belousov  wrote:
>On Tue, Jan 04, 2011 at 11:40:45AM +0100, Giorgos Keramidas wrote:
>>On Tue, 04 Jan 2011 11:36:38 +0100, Giorgos Keramidas  
>>wrote:
>>> Since the pattern of converting strings to int-derivative values appears
>>> multiple times, I'd probably prefer something like a new function that
>>> does the parsing *and* error-checking, to avoid duplication of errno
>>> checks, invalidchar checks, and so on, e.g. something like this near the
>>> top of rtprio.c:
>>>
>>> /*
>>>  * Parse an integer from 'string' into 'value'.  Return the first
>>>  * invalid character in 'endp', if endp is non-NULL.  The return 
>>> value
>>>  * of parseint is 0 on success, -1 for any parse error.
>>>  */
>>>
>>> int
>>> parseint(const char *string, const char **endp, int base, int 
>>> *value)
>>> ...
>   }
>
> Well, I think it shall be simplified. What about this ?

This looks much better than plain strtol() calls.  Thanks :)

> diff --git a/usr.sbin/rtprio/rtprio.c b/usr.sbin/rtprio/rtprio.c
> index 245f714..fc212b5 100644
> --- a/usr.sbin/rtprio/rtprio.c
> +++ b/usr.sbin/rtprio/rtprio.c
> @@ -37,31 +37,31 @@ __FBSDID("$FreeBSD$");
>
>  #include 
>  #include 
> -#include 
>
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
>  #include 
>
> -static void usage();
> +static int parseint(const char *, const char *);
> +static void usage(void);
>
>  int
> -main(argc, argv)
> - int argc;
> - char  **argv;
> +main(int argc, char *argv[])
>  {
> - char   *p;
> - int proc = 0;
>   struct rtprio rtp;
> + char *p;
> + pid_t proc;
>
>   /* find basename */
>   if ((p = rindex(argv[0], '/')) == NULL)
>   p = argv[0];
>   else
>   ++p;
> + proc = 0;
>
>   if (!strcmp(p, "rtprio"))
>   rtp.type = RTP_PRIO_REALTIME;
> @@ -70,12 +70,12 @@ main(argc, argv)
>
>   switch (argc) {
>   case 2:
> - proc = abs(atoi(argv[1]));  /* Should check if numeric
> -  * arg! */
> + proc = parseint(argv[1], "pid");
> + proc = abs(proc);
>   /* FALLTHROUGH */
>   case 1:
>   if (rtprio(RTP_LOOKUP, proc, &rtp) != 0)
> - err(1, "%s", argv[0]);
> + err(1, "RTP_LOOKUP");
>   printf("%s: ", p);
>   switch (rtp.type) {
>   case RTP_PRIO_REALTIME:
> @@ -103,19 +103,17 @@ main(argc, argv)
>   usage();
>   break;
>   }
> - } else {
> - rtp.prio = atoi(argv[1]);
> - }
> + } else
> + rtp.prio = parseint(argv[1], "priority");
>   } else {
>   usage();
>   break;
>   }
>
>   if (argv[2][0] == '-')
> - proc = -atoi(argv[2]);
> -
> + proc = parseint(argv[2] + 1, "pid");
>   if (rtprio(RTP_SET, proc, &rtp) != 0)
> - err(1, "%s", argv[0]);
> + err(1, "RTP_SET");
>
>   if (proc == 0) {
>   execvp(argv[2], &argv[2]);
> @@ -123,12 +121,28 @@ main(argc, argv)
>   }
>   exit(0);
>   }
> - exit (1);
> + exit(1);
> +}
> +
> +static int
> +parseint(const char *str, const char *errname)
> +{
> + char *endp;
> + long res;
> +
> + errno = 0;
> + res = strtol(str, &endp, 10);
> + if (errno != 0 || endp == str || *endp != '\0')
> + err(1, "%s shall be a number", errname);
> + if (res >= INT_MAX)
> + err(1, "Integer overflow parsing %s", errname);
> + return (res);
>  }
>
>  static void
> -usage()
> +usage(void)
>  {
> +
>   (void) fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n%s\n",
>   "usage: [id|rt]prio",
>   "   [id|rt]prio [-]pid",


pgp01wK7MOYI9.pgp
Description: PGP signature


Re: [patch] have rtprio check that arguments are numeric; change atoi to strtol

2011-01-04 Thread John Baldwin
On Tuesday, January 04, 2011 6:25:02 am Kostik Belousov wrote:
> On Tue, Jan 04, 2011 at 11:40:45AM +0100, Giorgos Keramidas wrote:
> @@ -123,12 +121,28 @@ main(argc, argv)
>   }
>   exit(0);
>   }
> - exit (1);
> + exit(1);
> +}
> +
> +static int
> +parseint(const char *str, const char *errname)
> +{
> + char *endp;
> + long res;
> +
> + errno = 0;
> + res = strtol(str, &endp, 10);
> + if (errno != 0 || endp == str || *endp != '\0')
> + err(1, "%s shall be a number", errname);

Small nit, maybe use 'must' instead of 'shall'.

-- 
John Baldwin
___
freebsd-hackers@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-hackers
To unsubscribe, send any mail to "freebsd-hackers-unsubscr...@freebsd.org"


Re: [patch] have rtprio check that arguments are numeric; change atoi to strtol

2011-01-04 Thread Alexander Best
On Tue Jan  4 11, John Baldwin wrote:
> On Tuesday, January 04, 2011 6:25:02 am Kostik Belousov wrote:
> > On Tue, Jan 04, 2011 at 11:40:45AM +0100, Giorgos Keramidas wrote:
> > @@ -123,12 +121,28 @@ main(argc, argv)
> > }
> > exit(0);
> > }
> > -   exit (1);
> > +   exit(1);
> > +}
> > +
> > +static int
> > +parseint(const char *str, const char *errname)
> > +{
> > +   char *endp;
> > +   long res;
> > +
> > +   errno = 0;
> > +   res = strtol(str, &endp, 10);
> > +   if (errno != 0 || endp == str || *endp != '\0')
> > +   err(1, "%s shall be a number", errname);
> 
> Small nit, maybe use 'must' instead of 'shall'.

it seems at some point there has been a massive usage of the term 'shall' in
manual pages, which people tried to get rid of. hence the
'usr/share/examples/mdoc/deshallify.sh' script.

maybe this should be noted in style(9)?

cheers.
alex

> 
> -- 
> John Baldwin

-- 
a13x
___
freebsd-hackers@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-hackers
To unsubscribe, send any mail to "freebsd-hackers-unsubscr...@freebsd.org"


Re: [patch] have rtprio check that arguments are numeric; change atoi to strtol

2011-01-04 Thread Garrett Cooper
On Jan 4, 2011, at 5:49 AM, Alexander Best wrote:

> On Tue Jan  4 11, John Baldwin wrote:
>> On Tuesday, January 04, 2011 6:25:02 am Kostik Belousov wrote:
>>> On Tue, Jan 04, 2011 at 11:40:45AM +0100, Giorgos Keramidas wrote:
>>> @@ -123,12 +121,28 @@ main(argc, argv)
>>> }
>>> exit(0);
>>> }
>>> -   exit (1);
>>> +   exit(1);
>>> +}
>>> +
>>> +static int
>>> +parseint(const char *str, const char *errname)
>>> +{
>>> +   char *endp;
>>> +   long res;
>>> +
>>> +   errno = 0;
>>> +   res = strtol(str, &endp, 10);
>>> +   if (errno != 0 || endp == str || *endp != '\0')
>>> +   err(1, "%s shall be a number", errname);
>> 
>> Small nit, maybe use 'must' instead of 'shall'.
> 
> it seems at some point there has been a massive usage of the term 'shall' in
> manual pages, which people tried to get rid of. hence the
> 'usr/share/examples/mdoc/deshallify.sh' script.

I know shall is used widely by opengroup when describing definitions and 
interfaces in the POSIX standards, but the connotation in English is very 
squishy, so I agree with John that must would be better.

BTW, only if errno was non-zero would using err(3) be logical. Otherwise it 
will just produce noise :).

> maybe this should be noted in style(9)?

Thanks,
-Garrett___
freebsd-hackers@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-hackers
To unsubscribe, send any mail to "freebsd-hackers-unsubscr...@freebsd.org"


Re: [patch] have rtprio check that arguments are numeric; change atoi to strtol

2011-01-04 Thread Giorgos Keramidas
On Tue, 4 Jan 2011 08:58:48 -0800, Garrett Cooper  wrote:
 +  errno = 0;
 +  res = strtol(str, &endp, 10);
 +  if (errno != 0 || endp == str || *endp != '\0')
 +  err(1, "%s shall be a number", errname);
>>>
>>> Small nit, maybe use 'must' instead of 'shall'.
>>
>> it seems at some point there has been a massive usage of the term
>> 'shall' in manual pages, which people tried to get rid of. hence the
>> 'usr/share/examples/mdoc/deshallify.sh' script.
>
> I know shall is used widely by opengroup when describing definitions
> and interfaces in the POSIX standards, but the connotation in English
> is very squishy, so I agree with John that must would be better.
>
> BTW, only if errno was non-zero would using err(3) be
> logical. Otherwise it will just produce noise :).

That's a good point.  I think we should change err() to errx() there.

___
freebsd-hackers@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-hackers
To unsubscribe, send any mail to "freebsd-hackers-unsubscr...@freebsd.org"


Re: [patch] have rtprio check that arguments are numeric; change atoi to strtol

2011-01-04 Thread Garrett Cooper
On Jan 4, 2011, at 10:12 AM, Giorgos Keramidas wrote:

> On Tue, 4 Jan 2011 08:58:48 -0800, Garrett Cooper  wrote:
> + errno = 0;
> + res = strtol(str, &endp, 10);
> + if (errno != 0 || endp == str || *endp != '\0')
> + err(1, "%s shall be a number", errname);
 
 Small nit, maybe use 'must' instead of 'shall'.
>>> 
>>> it seems at some point there has been a massive usage of the term
>>> 'shall' in manual pages, which people tried to get rid of. hence the
>>> 'usr/share/examples/mdoc/deshallify.sh' script.
>> 
>> I know shall is used widely by opengroup when describing definitions
>> and interfaces in the POSIX standards, but the connotation in English
>> is very squishy, so I agree with John that must would be better.
>> 
>> BTW, only if errno was non-zero would using err(3) be
>> logical. Otherwise it will just produce noise :).
> 
> That's a good point.  I think we should change err() to errx() there.

kib was quick and already did it in r216967.
Cheers!
-Garrett___
freebsd-hackers@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-hackers
To unsubscribe, send any mail to "freebsd-hackers-unsubscr...@freebsd.org"