mirror of
https://github.com/kdave/btrfs-progs
synced 2024-12-24 23:22:27 +00:00
btrfs-progs: Improve the parse_size() error message
When using parse_size(), even non-numeric value is passed, it will only give error message "ERROR: size value is empty", which is quite confusing for end users. This patch will introduce more meaningful error message for the following new cases 1) Invalid size string (non-numeric string) 2) Minus size value (like "-1K") Also this patch will take full use of endptr returned by strtoll() to reduce unneeded loop. Signed-off-by: Qu Wenruo <quwenruo@cn.fujitsu.com> Signed-off-by: David Sterba <dsterba@suse.cz>
This commit is contained in:
parent
4da2751451
commit
445a3a0a51
70
utils.c
70
utils.c
@ -1638,20 +1638,57 @@ scan_again:
|
||||
return 0;
|
||||
}
|
||||
|
||||
u64 parse_size(char *s)
|
||||
/*
|
||||
* A not-so-good version fls64. No fascinating optimization since
|
||||
* no one except parse_size use it
|
||||
*/
|
||||
static int fls64(u64 x)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i <64; i++)
|
||||
if (x << i & (1UL << 63))
|
||||
return 64 - i;
|
||||
return 64 - i;
|
||||
}
|
||||
|
||||
u64 parse_size(char *s)
|
||||
{
|
||||
char c;
|
||||
char *endptr;
|
||||
u64 mult = 1;
|
||||
u64 ret;
|
||||
|
||||
for (i = 0; s && s[i] && isdigit(s[i]); i++) ;
|
||||
if (!i) {
|
||||
fprintf(stderr, "ERROR: size value is empty\n");
|
||||
exit(50);
|
||||
if (!s) {
|
||||
fprintf(stderr, "ERROR: Size value is empty\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (s[i]) {
|
||||
c = tolower(s[i]);
|
||||
if (s[0] == '-') {
|
||||
fprintf(stderr,
|
||||
"ERROR: Size value '%s' is less equal than 0\n", s);
|
||||
exit(1);
|
||||
}
|
||||
ret = strtoull(s, &endptr, 10);
|
||||
if (endptr == s) {
|
||||
fprintf(stderr, "ERROR: Size value '%s' is invalid\n", s);
|
||||
exit(1);
|
||||
}
|
||||
if (endptr[0] && endptr[1]) {
|
||||
fprintf(stderr, "ERROR: Illegal suffix contains character '%c' in wrong position\n",
|
||||
endptr[1]);
|
||||
exit(1);
|
||||
}
|
||||
/*
|
||||
* strtoll returns LLONG_MAX when overflow, if this happens,
|
||||
* need to call strtoull to get the real size
|
||||
*/
|
||||
if (errno == ERANGE && ret == ULLONG_MAX) {
|
||||
fprintf(stderr,
|
||||
"ERROR: Size value '%s' is too large for u64\n", s);
|
||||
exit(1);
|
||||
}
|
||||
if (endptr[0]) {
|
||||
c = tolower(endptr[0]);
|
||||
switch (c) {
|
||||
case 'e':
|
||||
mult *= 1024;
|
||||
@ -1674,18 +1711,19 @@ u64 parse_size(char *s)
|
||||
case 'b':
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "ERROR: Unknown size descriptor "
|
||||
"'%c'\n", c);
|
||||
fprintf(stderr, "ERROR: Unknown size descriptor '%c'\n",
|
||||
c);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
if (s[i] && s[i+1]) {
|
||||
fprintf(stderr, "ERROR: Illegal suffix contains "
|
||||
"character '%c' in wrong position\n",
|
||||
s[i+1]);
|
||||
exit(51);
|
||||
/* Check whether ret * mult overflow */
|
||||
if (fls64(ret) + fls64(mult) - 1 > 64) {
|
||||
fprintf(stderr,
|
||||
"ERROR: Size value '%s' is too large for u64\n", s);
|
||||
exit(1);
|
||||
}
|
||||
return strtoull(s, NULL, 10) * mult;
|
||||
ret *= mult;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int open_file_or_dir3(const char *fname, DIR **dirstream, int open_flags)
|
||||
|
Loading…
Reference in New Issue
Block a user