mirror of
https://github.com/kdave/btrfs-progs
synced 2024-12-25 15:42:23 +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;
|
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;
|
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 c;
|
||||||
|
char *endptr;
|
||||||
u64 mult = 1;
|
u64 mult = 1;
|
||||||
|
u64 ret;
|
||||||
|
|
||||||
for (i = 0; s && s[i] && isdigit(s[i]); i++) ;
|
if (!s) {
|
||||||
if (!i) {
|
fprintf(stderr, "ERROR: Size value is empty\n");
|
||||||
fprintf(stderr, "ERROR: size value is empty\n");
|
exit(1);
|
||||||
exit(50);
|
|
||||||
}
|
}
|
||||||
|
if (s[0] == '-') {
|
||||||
if (s[i]) {
|
fprintf(stderr,
|
||||||
c = tolower(s[i]);
|
"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) {
|
switch (c) {
|
||||||
case 'e':
|
case 'e':
|
||||||
mult *= 1024;
|
mult *= 1024;
|
||||||
@ -1674,18 +1711,19 @@ u64 parse_size(char *s)
|
|||||||
case 'b':
|
case 'b':
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "ERROR: Unknown size descriptor "
|
fprintf(stderr, "ERROR: Unknown size descriptor '%c'\n",
|
||||||
"'%c'\n", c);
|
c);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (s[i] && s[i+1]) {
|
/* Check whether ret * mult overflow */
|
||||||
fprintf(stderr, "ERROR: Illegal suffix contains "
|
if (fls64(ret) + fls64(mult) - 1 > 64) {
|
||||||
"character '%c' in wrong position\n",
|
fprintf(stderr,
|
||||||
s[i+1]);
|
"ERROR: Size value '%s' is too large for u64\n", s);
|
||||||
exit(51);
|
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)
|
int open_file_or_dir3(const char *fname, DIR **dirstream, int open_flags)
|
||||||
|
Loading…
Reference in New Issue
Block a user