From 683f27fbb68ca2028a7b3468f17164d484df2759 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Andr=C3=A9=20Draszik?= Date: Thu, 25 Aug 2016 13:14:59 +0100 Subject: [PATCH] lib: add utility function nl_strerror_l() MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit libnl currently uses strerror_r() throughout, but this is problematic because there is a non-standard GNU version implemented in glibc, and the standard POSIX version, which differ in signature. When using glibc, one can choose between the two versions using feature test macros _GNU_SOURCE and _POSIX_C_SOURCE. Given libnl is built using the former, we always get the glibc special version, and all code so far has been written for that non-standard version. Other C libraries like musl on the other hand only try to be posix compliant, and only ever provide the posix version of strerror_r(), which has a different signature. The alternative is to use strerror_l() rather than strerror_r() http://austingroupbugs.net/view.php?id=655 - this will avoid the non-confirming versions issue - strerror_l() is now recommended by POSIX to replace strerror_r() usage So rather than changing all uses of strerror_r() to be in line with posix, we are going to switch to the recommended interface strerror_l(). Since strerror_l() is slightly more difficuly to use, we add a little (private) wrapper that we can use from all current callsites of strerror_r(). Signed-off-by: André Draszik Reviewed-by: Stephane Ayotte Signed-off-by: Thomas Haller --- include/Makefile.am | 1 + include/netlink-private/utils.h | 17 +++++++++++++++++ lib/utils.c | 24 ++++++++++++++++++++++++ libnl-3.sym | 5 +++++ 4 files changed, 47 insertions(+) create mode 100644 include/netlink-private/utils.h diff --git a/include/Makefile.am b/include/Makefile.am index 804e984..f8b977a 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -166,6 +166,7 @@ noinst_HEADERS = \ netlink-private/socket.h \ netlink-private/tc.h \ netlink-private/types.h \ + netlink-private/utils.h \ netlink-private/cache-api.h \ netlink-private/object-api.h \ netlink-private/route/link/api.h \ diff --git a/include/netlink-private/utils.h b/include/netlink-private/utils.h new file mode 100644 index 0000000..77aadb3 --- /dev/null +++ b/include/netlink-private/utils.h @@ -0,0 +1,17 @@ +/* + * netlink-private/utils.h Local Utility Functions + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation version 2.1 + * of the License. + * + * Copyright (c) 2003-2012 Thomas Graf + */ + +#ifndef NETLINK_UTILS_PRIV_H_ +#define NETLINK_UTILS_PRIV_H_ + +extern const char * nl_strerror_l(int err); + +#endif diff --git a/lib/utils.c b/lib/utils.c index 61c3d95..c1c1b72 100644 --- a/lib/utils.c +++ b/lib/utils.c @@ -25,10 +25,12 @@ */ #include +#include #include #include #include #include /* exit() */ +#include /** * Global variable indicating the desired level of debugging output. @@ -118,6 +120,28 @@ int __nl_read_num_str_file(const char *path, int (*cb)(long, const char *)) return 0; } + +const char *nl_strerror_l(int err) +{ + int errno_save = errno; + locale_t loc = newlocale(LC_MESSAGES_MASK, "", (locale_t)0); + const char *buf; + + if (loc == (locale_t)0) { + if (errno == ENOENT) + loc = newlocale(LC_MESSAGES_MASK, + "POSIX", (locale_t)0); + } + if (loc != (locale_t)0) { + buf = strerror_l(err, loc); + freelocale(loc); + } else { + buf = "newlocale() failed"; + } + + errno = errno_save; + return buf; +} /** @endcond */ /** diff --git a/libnl-3.sym b/libnl-3.sym index 4e09bdd..9119e66 100644 --- a/libnl-3.sym +++ b/libnl-3.sym @@ -351,3 +351,8 @@ libnl_3_2_28 { global: nl_object_diff64; } libnl_3_2_27; + +libnl_3_2_29 { +global: + nl_strerror_l; +} libnl_3_2_28; -- 2.40.0