aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorQu Wenruo <wqu@suse.com>2024-01-17 14:40:39 +1030
committerDavid Sterba <dsterba@suse.com>2024-01-18 02:09:07 +0100
commit8f8d94b8c932fc61e80573b5cf8cc73302fcfd3d (patch)
treed184fc6b9bea01ff0738dc55398f9c1e62eb8c47
parent2608354dc364ec0cf9593354d9d00de8a81dcbd1 (diff)
downloadbtrfs-progs-8f8d94b8c932fc61e80573b5cf8cc73302fcfd3d.tar.gz
btrfs-progs: use parse_u64() to implement arg_strtou64()
Both functions are just doing the same thing, the only difference is only in error handling, as parse_u64() requires callers to handle it, meanwhile arg_strtou64() would call exit(1). This patch would convert arg_strtou64() to utilize parse_u64(), and use the return value to output different error messages. This also means the return value of parse_u64() would be more than just 0 or 1, but -EINVAL for invalid string (including no numeric string at all, has any tailing characters, or minus value), and -ERANGE for overflow. The existing callers are only checking if the return value is 0, thus not really affected. Signed-off-by: Qu Wenruo <wqu@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
-rw-r--r--common/parse-utils.c19
-rw-r--r--common/string-utils.c26
-rw-r--r--common/string-utils.h2
3 files changed, 30 insertions, 17 deletions
diff --git a/common/parse-utils.c b/common/parse-utils.c
index 3d9a6d63..bc913c23 100644
--- a/common/parse-utils.c
+++ b/common/parse-utils.c
@@ -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 large 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;
diff --git a/common/string-utils.c b/common/string-utils.c
index e338afa7..ba5cc55a 100644
--- a/common/string-utils.c
+++ b/common/string-utils.c
@@ -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;
}
diff --git a/common/string-utils.h b/common/string-utils.h
index ade8fcd1..a7ac8f5c 100644
--- a/common/string-utils.h
+++ b/common/string-utils.h
@@ -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);