Skip to content

Commit

Permalink
lib: add utility function nl_strerror_l()
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
andred authored and thom311 committed Aug 25, 2016
1 parent b3dfa79 commit 683f27f
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 0 deletions.
1 change: 1 addition & 0 deletions include/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -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 \
Expand Down
17 changes: 17 additions & 0 deletions include/netlink-private/utils.h
Original file line number Diff line number Diff line change
@@ -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
24 changes: 24 additions & 0 deletions lib/utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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 */

/**
Expand Down
5 changes: 5 additions & 0 deletions libnl-3.sym
Original file line number Diff line number Diff line change
Expand Up @@ -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;

0 comments on commit 683f27f

Please sign in to comment.