From 59251cae459a013c68e4f88794f0a9bd0deca51c Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Fri, 18 Aug 2023 14:56:42 +0200 Subject: [PATCH] std-aux: extract and add _nm_strerror_r() helper We have nm_strerror_native_r(), which is the wrapper around strerror_r() that we want to use in glib components (it also will ensure that the string is valid UTF-8). However, it's not usable from non-glib components. Move the part that abstracts strerror_r() out to libnm-std-aux as _nm_strerror_r(). The purpose is that non-glib componenent can use the thread-safe wrapper around strerror_r(). --- src/libnm-glib-aux/nm-errno.c | 23 ++++-------------- src/libnm-std-aux/nm-std-utils.c | 40 ++++++++++++++++++++++++++++++++ src/libnm-std-aux/nm-std-utils.h | 2 ++ 3 files changed, 46 insertions(+), 19 deletions(-) diff --git a/src/libnm-glib-aux/nm-errno.c b/src/libnm-glib-aux/nm-errno.c index b76386a6f..682bfea2a 100644 --- a/src/libnm-glib-aux/nm-errno.c +++ b/src/libnm-glib-aux/nm-errno.c @@ -6,6 +6,7 @@ #include "libnm-glib-aux/nm-default-glib-i18n-lib.h" #include "nm-errno.h" +#include "libnm-std-aux/nm-std-utils.h" /*****************************************************************************/ @@ -100,26 +101,10 @@ nm_strerror(int nmerr) const char * nm_strerror_native_r(int errsv, char *buf, gsize buf_size) { - char *buf2; + NM_AUTO_PROTECT_ERRNO(errsv2); + const char *buf2; - nm_assert(buf); - nm_assert(buf_size > 0); - -#if (!defined(__GLIBC__) && !defined(__UCLIBC__)) || ((_POSIX_C_SOURCE >= 200112L) && !_GNU_SOURCE) - /* XSI-compliant */ - { - int errno_saved = errno; - - if (strerror_r(errsv, buf, buf_size) != 0) { - g_snprintf(buf, buf_size, "Unspecified errno %d", errsv); - errno = errno_saved; - } - buf2 = buf; - } -#else - /* GNU-specific */ - buf2 = strerror_r(errsv, buf, buf_size); -#endif + buf2 = _nm_strerror_r(errsv, buf, buf_size); /* like g_strerror(), ensure that the error message is UTF-8. */ if (!g_get_charset(NULL) && !g_utf8_validate(buf2, -1, NULL)) { diff --git a/src/libnm-std-aux/nm-std-utils.c b/src/libnm-std-aux/nm-std-utils.c index 8901378cb..8bc109f2e 100644 --- a/src/libnm-std-aux/nm-std-utils.c +++ b/src/libnm-std-aux/nm-std-utils.c @@ -92,3 +92,43 @@ out_huge: } return SIZE_MAX; } + +/*****************************************************************************/ + +/** + * _nm_strerror_r: + * @errsv: the errno passed to strerror_r() + * @buf: the string buffer, must be non-null + * @buf_size: the size of the buffer, must be positive. + * + * A wrapper around strerror_r(). Does little else, aside clearing up the + * confusion about the different versions of the function. + * + * errno is preserved. + * + * Returns: the error string. This is either a static strong or @buf. It + * is not guaranteed to be @buf. + */ +const char * +_nm_strerror_r(int errsv, char *buf, size_t buf_size) +{ + NM_AUTO_PROTECT_ERRNO(errsv2); + char *buf2; + + nm_assert(buf); + nm_assert(buf_size > 0); + +#if (!defined(__GLIBC__) && !defined(__UCLIBC__)) || ((_POSIX_C_SOURCE >= 200112L) && !_GNU_SOURCE) + /* XSI-compliant */ + if (strerror_r(errsv, buf, buf_size) != 0) { + snprintf(buf, buf_size, "Unspecified errno %d", errsv); + } + buf2 = buf; +#else + /* GNU-specific */ + buf2 = strerror_r(errsv, buf, buf_size); +#endif + + nm_assert(buf2); + return buf2; +} diff --git a/src/libnm-std-aux/nm-std-utils.h b/src/libnm-std-aux/nm-std-utils.h index 6aa787eb6..015444c93 100644 --- a/src/libnm-std-aux/nm-std-utils.h +++ b/src/libnm-std-aux/nm-std-utils.h @@ -35,4 +35,6 @@ size_t nm_utils_get_next_realloc_size(bool true_realloc, size_t requested); +const char *_nm_strerror_r(int errsv, char *buf, size_t buf_size); + #endif /* __NM_STD_UTILS_H__ */