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().
This commit is contained in:
Thomas Haller
2023-08-18 14:56:42 +02:00
committed by Beniamino Galvani
parent b53f929f40
commit 59251cae45
3 changed files with 46 additions and 19 deletions

View File

@@ -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)) {

View File

@@ -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;
}

View File

@@ -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__ */