From 47d4be12c3997343e436c6cca89aefbbbeb70863 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Thu, 10 Sep 2015 10:02:00 +0200 Subject: cutils: work around platform differences in strto{l,ul,ll,ull} Linux returns 0 if no conversion was made, while OS X and presumably the BSDs return EINVAL. The OS X convention rejects more invalid inputs, so convert to it and adjust the test case. Windows returns 1 from strtoul and strtoull (instead of -1) for negative out-of-range input; fix it up. Reported-by: Peter Maydell Signed-off-by: Paolo Bonzini --- util/cutils.c | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) (limited to 'util') diff --git a/util/cutils.c b/util/cutils.c index 67c50e5ae7..84ceaff48c 100644 --- a/util/cutils.c +++ b/util/cutils.c @@ -361,9 +361,15 @@ int64_t strtosz(const char *nptr, char **end) /** * Helper function for qemu_strto*l() functions. */ -static int check_strtox_error(const char **next, char *endptr, +static int check_strtox_error(const char *p, char *endptr, const char **next, int err) { + /* If no conversion was performed, prefer BSD behavior over glibc + * behavior. + */ + if (err == 0 && endptr == p) { + err = EINVAL; + } if (!next && *endptr) { return -EINVAL; } @@ -412,7 +418,7 @@ int qemu_strtol(const char *nptr, const char **endptr, int base, } else { errno = 0; *result = strtol(nptr, &p, base); - err = check_strtox_error(endptr, p, errno); + err = check_strtox_error(nptr, p, endptr, errno); } return err; } @@ -443,7 +449,11 @@ int qemu_strtoul(const char *nptr, const char **endptr, int base, } else { errno = 0; *result = strtoul(nptr, &p, base); - err = check_strtox_error(endptr, p, errno); + /* Windows returns 1 for negative out-of-range values. */ + if (errno == ERANGE) { + *result = -1; + } + err = check_strtox_error(nptr, p, endptr, errno); } return err; } @@ -466,7 +476,7 @@ int qemu_strtoll(const char *nptr, const char **endptr, int base, } else { errno = 0; *result = strtoll(nptr, &p, base); - err = check_strtox_error(endptr, p, errno); + err = check_strtox_error(nptr, p, endptr, errno); } return err; } @@ -489,7 +499,11 @@ int qemu_strtoull(const char *nptr, const char **endptr, int base, } else { errno = 0; *result = strtoull(nptr, &p, base); - err = check_strtox_error(endptr, p, errno); + /* Windows returns 1 for negative out-of-range values. */ + if (errno == ERANGE) { + *result = -1; + } + err = check_strtox_error(nptr, p, endptr, errno); } return err; } -- cgit v1.2.3-55-g7522