@@ -31,14 +31,31 @@
#include "common/messages.h"
#include "common/utils.h"
+/*
+ * Parse a string to u64.
+ *
+ * Return 0 if there is a valid numeric string and result would be stored in
+ * @result.
+ * Return -EINVAL if the string is not valid (no numeric string at all, or
+ * has any tailing characters, or a negative value).
+ * Return -ERANGE if the value is too larger for u64.
+ */
int parse_u64(const char *str, u64 *result)
{
char *endptr;
u64 val;
+ /*
+ * Although strtoull accepts a negative number and converts it u64, we
+ * don't really want to utilize this as the helper is meant for u64 only.
+ */
+ if (str[0] == '-')
+ return -EINVAL;
val = strtoull(str, &endptr, 10);
if (*endptr)
- return 1;
+ return -EINVAL;
+ if (val == ULLONG_MAX && errno == ERANGE)
+ return -ERANGE;
*result = val;
return 0;
@@ -20,6 +20,7 @@
#include <limits.h>
#include "common/string-utils.h"
#include "common/messages.h"
+#include "common/parse-utils.h"
int string_is_numerical(const char *str)
{
@@ -50,25 +51,18 @@ int string_has_prefix(const char *str, const char *prefix)
u64 arg_strtou64(const char *str)
{
u64 value;
- char *ptr_parse_end = NULL;
+ int ret;
- value = strtoull(str, &ptr_parse_end, 0);
- if (ptr_parse_end && *ptr_parse_end != '\0') {
- error("%s is not a valid numeric value", str);
- exit(1);
- }
-
- /*
- * if we pass a negative number to strtoull, it will return an
- * unexpected number to us, so let's do the check ourselves.
- */
- if (str[0] == '-') {
- error("%s: negative value is invalid", str);
- exit(1);
- }
- if (value == ULLONG_MAX) {
+ ret = parse_u64(str, &value);
+ if (ret == -ERANGE) {
error("%s is too large", str);
exit(1);
+ } else if (ret == -EINVAL) {
+ if (str[0] == '-')
+ error("%s: negative value is invalid", str);
+ else
+ error("%s is not a valid numeric value", str);
+ exit(1);
}
return value;
}
@@ -17,6 +17,8 @@
#ifndef __BTRFS_STRING_UTILS_H__
#define __BTRFS_STRING_UTILS_H__
+#include "kerncompat.h"
+
int string_is_numerical(const char *str);
int string_has_prefix(const char *str, const char *prefix);
u64 arg_strtou64(const char *str);