summaryrefslogtreecommitdiffstats
path: root/lib/utils.c
diff options
context:
space:
mode:
authorAndré Draszik <adraszik@tycoint.com>2016-08-25 12:14:59 (GMT)
committerThomas Haller <thaller@redhat.com>2016-08-25 15:32:57 (GMT)
commit683f27fbb68ca2028a7b3468f17164d484df2759 (patch)
treeabd97cbd8503dfc7983c30241e70b97360c93ea3 /lib/utils.c
parentb3dfa79010dcb0f12d68903ba8fb8367d8bee0da (diff)
downloadlibnl-683f27fbb68ca2028a7b3468f17164d484df2759.zip
libnl-683f27fbb68ca2028a7b3468f17164d484df2759.tar.gz
libnl-683f27fbb68ca2028a7b3468f17164d484df2759.tar.bz2
lib: add utility function nl_strerror_l()
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 <adraszik@tycoint.com> Reviewed-by: Stephane Ayotte <sayotte@tycoint.com> Signed-off-by: Thomas Haller <thaller@redhat.com>
Diffstat (limited to 'lib/utils.c')
-rw-r--r--lib/utils.c24
1 files changed, 24 insertions, 0 deletions
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 <netlink-private/netlink.h>
+#include <netlink-private/utils.h>
#include <netlink/netlink.h>
#include <netlink/utils.h>
#include <linux/socket.h>
#include <stdlib.h> /* exit() */
+#include <locale.h>
/**
* 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 */
/**