[systemd-devel] [RFC 22/25] support POSIX strerror_r returning int
Emil Renner Berthing
systemd at esmil.dk
Thu Sep 18 06:24:58 PDT 2014
---
configure.ac | 2 ++
src/journal/journal-send.c | 36 +++++++++++++++++++++++++++---------
src/libsystemd/sd-bus/bus-error.c | 14 +++++++++++++-
3 files changed, 42 insertions(+), 10 deletions(-)
diff --git a/configure.ac b/configure.ac
index 9cd4c05..3f17833 100644
--- a/configure.ac
+++ b/configure.ac
@@ -336,6 +336,8 @@ AC_CHECK_DECLS([IFLA_MACVLAN_FLAGS,
#include <linux/if_bridge.h>
]])
+AC_FUNC_STRERROR_R
+
# This makes sure pkg.m4 is available.
m4_pattern_forbid([^_?PKG_[A-Z_]+$],[*** pkg.m4 missing, please install pkg-config])
diff --git a/src/journal/journal-send.c b/src/journal/journal-send.c
index 9ca4a0b..62b40b2 100644
--- a/src/journal/journal-send.c
+++ b/src/journal/journal-send.c
@@ -341,6 +341,29 @@ _public_ int sd_journal_sendv(const struct iovec *iov, int n) {
return 0;
}
+#ifdef STRERROR_R_CHAR_P
+static int posix_strerror_r(int errnum, char *buf, size_t buflen) {
+ char *res;
+
+ errno = 0;
+ res = strerror_r(errnum, buf, buflen);
+ if (errno)
+ return errno;
+
+ if (res != buf) {
+ size_t len = strlen(res)+1;
+
+ if (len > buflen)
+ return ERANGE;
+
+ memmove(buf, res, len);
+ }
+ return 0;
+}
+#else
+#define posix_strerror_r strerror_r
+#endif
+
static int fill_iovec_perror_and_send(const char *message, int skip, struct iovec iov[]) {
PROTECT_ERRNO;
size_t n, k;
@@ -350,16 +373,11 @@ static int fill_iovec_perror_and_send(const char *message, int skip, struct iove
for (;;) {
char buffer[n];
- char* j;
+ int ret = posix_strerror_r(_saved_errno_, buffer + 8 + k, n - 8 - k);
- errno = 0;
- j = strerror_r(_saved_errno_, buffer + 8 + k, n - 8 - k);
- if (errno == 0) {
+ if (ret == 0) {
char error[6 + 10 + 1]; /* for a 32bit value */
- if (j != buffer + 8 + k)
- memmove(buffer + 8 + k, j, strlen(j)+1);
-
memcpy(buffer, "MESSAGE=", 8);
if (k > 0) {
@@ -377,8 +395,8 @@ static int fill_iovec_perror_and_send(const char *message, int skip, struct iove
return sd_journal_sendv(iov, skip + 3);
}
- if (errno != ERANGE)
- return -errno;
+ if (ret != ERANGE)
+ return -ret;
n *= 2;
}
diff --git a/src/libsystemd/sd-bus/bus-error.c b/src/libsystemd/sd-bus/bus-error.c
index c2e41fb..14bbaca 100644
--- a/src/libsystemd/sd-bus/bus-error.c
+++ b/src/libsystemd/sd-bus/bus-error.c
@@ -291,6 +291,18 @@ _public_ int sd_bus_error_get_errno(const sd_bus_error* e) {
return bus_error_name_to_errno(e->name);
}
+#ifdef STRERROR_R_CHAR_P
+#define gnu_strerror_r strerror_r
+#else
+static char *gnu_strerror_r(int errnum, char *buf, size_t buflen) {
+ int ret = strerror_r(errnum, buf, buflen);
+
+ if (ret)
+ errno = ret;
+ return buf;
+}
+#endif
+
static void bus_error_strerror(sd_bus_error *e, int error) {
size_t k = 64;
char *m;
@@ -305,7 +317,7 @@ static void bus_error_strerror(sd_bus_error *e, int error) {
return;
errno = 0;
- x = strerror_r(error, m, k);
+ x = gnu_strerror_r(error, m, k);
if (errno == ERANGE || strlen(x) >= k - 1) {
free(m);
k *= 2;
--
2.1.0
More information about the systemd-devel
mailing list