| From 683f27fbb68ca2028a7b3468f17164d484df2759 Mon Sep 17 00:00:00 2001 |
| From: =?UTF-8?q?Andr=C3=A9=20Draszik?= <adraszik@tycoint.com> |
| Date: Thu, 25 Aug 2016 13:14:59 +0100 |
| Subject: [PATCH 1/3] lib: add utility function nl_strerror_l() |
| MIME-Version: 1.0 |
| Content-Type: text/plain; charset=UTF-8 |
| 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 <adraszik@tycoint.com> |
| Reviewed-by: Stephane Ayotte <sayotte@tycoint.com> |
| Signed-off-by: Thomas Haller <thaller@redhat.com> |
| --- |
| Upstream-Status: Backport https://github.com/thom311/libnl/commit/683f27fbb68ca2028a7b3468f17164d484df2759 |
| 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 <tgraf@suug.ch> |
| + */ |
| + |
| +#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 <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 */ |
| |
| /** |
| 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.9.3 |
| |