From 500f0b96ae93cc0dbcb63124c46956cf532031c3 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 1 Apr 2020 12:30:20 +0200 Subject: [PATCH] all: use wrappers for g_ascii_strtoll(), g_ascii_strtoull(), g_ascii_strtod() Sometimes these function may set errno to unexpected values like EAGAIN. This causes confusion. Avoid that by using our own wrappers that retry in that case. For example, in rhbz#1797915 we have failures like: errno = 0; v = g_ascii_strtoll ("10", 0, &end); if (errno != 0) g_assert_not_reached (); as g_ascii_strtoll() would return 10, but also set errno to EAGAIN. Work around that by using wrapper functions that retry. This certainly should be fixed in glib (or glibc), but the issues are severe enough to warrant a workaround. Note that our workarounds are very defensive. We only retry 2 times, if we get an unexpected errno value. This is in the hope to recover from a spurious EAGAIN. It won't recover from other errors. https://bugzilla.redhat.com/show_bug.cgi?id=1797915 (cherry picked from commit 7e49f4a199beb9b8012ec554c4a9ad1c851f7ff2) (cherry picked from commit eec2740d718db4c73bf4c31b97852ee83bb3dfa7) --- libnm-core/nm-utils.c | 4 ++-- shared/nm-glib-aux/nm-shared-utils.c | 8 ++++---- src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/libnm-core/nm-utils.c b/libnm-core/nm-utils.c index 8f2b40184a..2848e83c5c 100644 --- a/libnm-core/nm-utils.c +++ b/libnm-core/nm-utils.c @@ -2314,7 +2314,7 @@ _nm_utils_parse_tc_handle (const char *str, GError **error) nm_assert (str); - maj = g_ascii_strtoll (str, (char **) &sep, 0x10); + maj = nm_g_ascii_strtoll (str, (char **) &sep, 0x10); if (sep == str) goto fail; @@ -2323,7 +2323,7 @@ _nm_utils_parse_tc_handle (const char *str, GError **error) if (sep[0] == ':') { const char *str2 = &sep[1]; - min = g_ascii_strtoll (str2, (char **) &sep, 0x10); + min = nm_g_ascii_strtoll (str2, (char **) &sep, 0x10); sep = nm_str_skip_leading_spaces (sep); if (sep[0] != '\0') goto fail; diff --git a/shared/nm-glib-aux/nm-shared-utils.c b/shared/nm-glib-aux/nm-shared-utils.c index 858f8959cb..1c672d2c70 100644 --- a/shared/nm-glib-aux/nm-shared-utils.c +++ b/shared/nm-glib-aux/nm-shared-utils.c @@ -892,7 +892,7 @@ _nm_utils_ascii_str_to_int64 (const char *str, guint base, gint64 min, gint64 ma } errno = 0; - v = g_ascii_strtoll (str, (char **) &s, base); + v = nm_g_ascii_strtoll (str, (char **) &s, base); if (errno != 0) return fallback; @@ -928,7 +928,7 @@ _nm_utils_ascii_str_to_uint64 (const char *str, guint base, guint64 min, guint64 } errno = 0; - v = g_ascii_strtoull (str, (char **) &s, base); + v = nm_g_ascii_strtoull (str, (char **) &s, base); if (errno != 0) return fallback; @@ -947,8 +947,8 @@ _nm_utils_ascii_str_to_uint64 (const char *str, guint base, guint64 min, guint64 if ( v != 0 && str[0] == '-') { - /* I don't know why, but g_ascii_strtoull() accepts minus signs ("-2" gives 18446744073709551614). - * For "-0" that is OK, but otherwise not. */ + /* As documented, g_ascii_strtoull() accepts negative values, and returns their + * absolute value. We don't. */ errno = ERANGE; return fallback; } diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c index 82124c1be8..7971fba56d 100644 --- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c +++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c @@ -553,7 +553,7 @@ make_connection_setting (const char *file, char *endptr; double d; - d = g_ascii_strtod (v, &endptr); + d = nm_g_ascii_strtod (v, &endptr); endptr = nm_str_skip_leading_spaces (endptr); if ( errno == 0 && endptr[0] == '\0'