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>
This commit is contained in:
Qu Wenruo 2024-01-17 14:40:39 +10:30 committed by David Sterba
parent 2608354dc3
commit 8f8d94b8c9
3 changed files with 30 additions and 17 deletions

View File

@ -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;

View File

@ -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;
}

View File

@ -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);