summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2020-04-01 12:30:20 +0200
committerThomas Haller <thaller@redhat.com>2020-04-01 17:18:37 +0200
commit7e49f4a199beb9b8012ec554c4a9ad1c851f7ff2 (patch)
treefa8248e1a3abd11ebcaa89649092c3e9498fc693
parent3b58c5fef490cfdae632f5007c77267e47971734 (diff)
downloadNetworkManager-th/strtoll-workaround.tar.gz
all: use wrappers for g_ascii_strtoll(), g_ascii_strtoull(), g_ascii_strtod()th/strtoll-workaround
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
-rw-r--r--libnm-core/nm-utils.c4
-rw-r--r--shared/nm-glib-aux/nm-shared-utils.c26
-rw-r--r--src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c2
3 files changed, 8 insertions, 24 deletions
diff --git a/libnm-core/nm-utils.c b/libnm-core/nm-utils.c
index 2e4b0ceb44..24d9dfcb43 100644
--- a/libnm-core/nm-utils.c
+++ b/libnm-core/nm-utils.c
@@ -2299,7 +2299,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;
@@ -2308,7 +2308,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 52f4bff2fd..f1371801ca 100644
--- a/shared/nm-glib-aux/nm-shared-utils.c
+++ b/shared/nm-glib-aux/nm-shared-utils.c
@@ -1134,26 +1134,10 @@ _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) {
-#if NM_MORE_ASSERTS
- int errsv = errno;
-
- /* the caller must not pass an invalid @base. Hence, we expect the only failure that
- * can happen here is ERANGE, because invalid @str is not signaled via an errno according
- * to documentation. */
- if ( errsv != ERANGE
- || !NM_IN_SET (v, G_MININT64, G_MAXINT64)) {
- g_error ("g_ascii_strtoll() for \"%s\" failed with errno=%d (%s) and v=%"G_GINT64_FORMAT,
- str,
- errsv,
- nm_strerror_native (errsv),
- v);
- }
-#endif
+ if (errno != 0)
return fallback;
- }
if (s[0] != '\0') {
s = nm_str_skip_leading_spaces (s);
@@ -1186,7 +1170,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;
@@ -1205,8 +1189,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 f337d0d4d0..60bc504717 100644
--- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c
+++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c
@@ -560,7 +560,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'