Makefile: Link to the system logging library on Android
[fio.git] / parse.c
diff --git a/parse.c b/parse.c
index 196de1553b8e4992d499c299bc7bb7efa1f5be61..483a62f680cf8ba3dde1982afdb9aea63bcd6d73 100644 (file)
--- a/parse.c
+++ b/parse.c
@@ -373,12 +373,16 @@ int str_to_decimal(const char *str, long long *val, int kilo, void *data,
 #endif
 
        if (rc == 1) {
+               char *endptr;
+
                if (strstr(str, "0x") || strstr(str, "0X"))
                        base = 16;
                else
                        base = 10;
 
-               *val = strtoll(str, NULL, base);
+               *val = strtoll(str, &endptr, base);
+               if (*val == 0 && endptr == str)
+                       return 1;
                if (*val == LONG_MAX && errno == ERANGE)
                        return 1;
        }
@@ -506,6 +510,33 @@ static const char *opt_type_name(const struct fio_option *o)
        return "OPT_UNKNOWN?";
 }
 
+static bool val_too_large(const struct fio_option *o, unsigned long long val,
+                         bool is_uint)
+{
+       if (!o->maxval)
+               return false;
+
+       if (is_uint) {
+               if ((int) val < 0)
+                       return (int) val > (int) o->maxval;
+               return (unsigned int) val > o->maxval;
+       }
+
+       return val > o->maxval;
+}
+
+static bool val_too_small(const struct fio_option *o, unsigned long long val,
+                         bool is_uint)
+{
+       if (!o->minval)
+               return false;
+
+       if (is_uint)
+               return (int) val < o->minval;
+
+       return val < o->minval;
+}
+
 static int __handle_option(const struct fio_option *o, const char *ptr,
                           void *data, int first, int more, int curr)
 {
@@ -575,8 +606,7 @@ static int __handle_option(const struct fio_option *o, const char *ptr,
                if (!is_time && o->is_time)
                        is_time = o->is_time;
 
-               tmp[sizeof(tmp) - 1] = '\0';
-               strncpy(tmp, ptr, sizeof(tmp) - 1);
+               snprintf(tmp, sizeof(tmp), "%s", ptr);
                p = strchr(tmp, ',');
                if (p)
                        *p = '\0';
@@ -595,12 +625,12 @@ static int __handle_option(const struct fio_option *o, const char *ptr,
                        return 1;
                }
 
-               if (o->maxval && ull > o->maxval) {
+               if (val_too_large(o, ull, o->type == FIO_OPT_INT)) {
                        log_err("%s: max value out of range: %llu"
                                " (%llu max)\n", o->name, ull, o->maxval);
                        return 1;
                }
-               if (o->minval && ull < o->minval) {
+               if (val_too_small(o, ull, o->type == FIO_OPT_INT)) {
                        log_err("%s: min value out of range: %lld"
                                " (%d min)\n", o->name, ull, o->minval);
                        return 1;
@@ -802,8 +832,7 @@ static int __handle_option(const struct fio_option *o, const char *ptr,
                char tmp[128];
                char *p1, *p2;
 
-               tmp[sizeof(tmp) - 1] = '\0';
-               strncpy(tmp, ptr, sizeof(tmp) - 1);
+               snprintf(tmp, sizeof(tmp), "%s", ptr);
 
                /* Handle bsrange with separate read,write values: */
                p1 = strchr(tmp, ',');