changeset 1638:184c98250cc5 draft

strtol() doesn't return error indicator for overflow, it just sets errno. So add estrtol() (which clears errno first), and xstrtol() (which error_exit()s on overflow).
author Rob Landley <rob@landley.net>
date Thu, 01 Jan 2015 16:28:51 -0600
parents 2c86e2cc1fd7
children 856b544f8fce
files lib/lib.c lib/lib.h
diffstat 2 files changed, 25 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/lib/lib.c	Thu Jan 01 16:19:40 2015 -0600
+++ b/lib/lib.c	Thu Jan 01 16:28:51 2015 -0600
@@ -233,13 +233,30 @@
   return rlist;
 }
 
+long estrtol(char *str, char **end, int base)
+{
+  errno = 0;
+
+  return strtol(str, end, base);
+}
+
+long xstrtol(char *str, char **end, int base)
+{
+  long l = estrtol(str, end, base);
+
+  if (errno) perror_exit("%s", str);
+
+  return l;
+}
+
 // atol() with the kilo/mega/giga/tera/peta/exa extensions.
 // (zetta and yotta don't fit in 64 bits.)
 long atolx(char *numstr)
 {
   char *c, *suffixes="cbkmgtpe", *end;
-  long val = strtol(numstr, &c, 0);
+  long val;
 
+  val = xstrtol(numstr, &c, 0);
   if (*c) {
     if (c != numstr && (end = strchr(suffixes, tolower(*c)))) {
       int shift = end-suffixes-2;
@@ -685,8 +702,9 @@
 
   if (pidstr) {
     char *s;
-    i = strtol(pidstr, &s, 10);
-    if (!*s) return i;
+
+    i = estrtol(pidstr, &s, 10);
+    if (!errno && !*s) return i;
 
     if (!strncasecmp(pidstr, "sig", 3)) pidstr+=3;
   }
@@ -715,8 +733,8 @@
 
   // Handle octal mode
   if (isdigit(*str)) {
-    mode = strtol(str, &s, 8);
-    if (*s || (mode & ~(07777))) goto barf;
+    mode = estrtol(str, &s, 8);
+    if (errno || *s || (mode & ~(07777))) goto barf;
 
     return mode | extrabits;
   }
--- a/lib/lib.h	Thu Jan 01 16:19:40 2015 -0600
+++ b/lib/lib.h	Thu Jan 01 16:28:51 2015 -0600
@@ -148,6 +148,8 @@
 int64_t peek(void *ptr, unsigned size);
 void poke(void *ptr, uint64_t val, int size);
 struct string_list *find_in_path(char *path, char *filename);
+long estrtol(char *str, char **end, int base);
+long xstrtol(char *str, char **end, int base);
 long atolx(char *c);
 long atolx_range(char *numstr, long low, long high);
 int numlen(long l);