summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 40fc2a5)
raw | patch | inline | side by side (parent: 40fc2a5)
author | oetiker <oetiker@a5681a0c-68f1-0310-ab6d-d61299d08faa> | |
Fri, 6 Mar 2009 05:40:17 +0000 (05:40 +0000) | ||
committer | oetiker <oetiker@a5681a0c-68f1-0310-ab6d-d61299d08faa> | |
Fri, 6 Mar 2009 05:40:17 +0000 (05:40 +0000) |
(e.g. the GNU libc) return a "char *" _and_ ignore the second argument (user
provided buffer). The configure script now checks for that behavior using
AC_FUNC_STRERROR_R. rrd_strerror() in rrd_thread_safe.c has been updated to
(hopefully) handle all possible cases.
Previously, rrd_strerror() would have returned "strerror_r failed. sorry!" in
mostly any cases when using glibc, since "if (strerror_r())" had been used to
check for errors which evaluates to true if a (non-NULL) pointer was returned.
Now, we, at least, return the error number in case anything else fails.
Thanks to Alessandro Iurlano for reporting this issue after spotting it in
collectd <http://collectd.org>.
patch by Sebastian Harl
git-svn-id: svn://svn.oetiker.ch/rrdtool/branches/1.3/program@1753 a5681a0c-68f1-0310-ab6d-d61299d08faa
provided buffer). The configure script now checks for that behavior using
AC_FUNC_STRERROR_R. rrd_strerror() in rrd_thread_safe.c has been updated to
(hopefully) handle all possible cases.
Previously, rrd_strerror() would have returned "strerror_r failed. sorry!" in
mostly any cases when using glibc, since "if (strerror_r())" had been used to
check for errors which evaluates to true if a (non-NULL) pointer was returned.
Now, we, at least, return the error number in case anything else fails.
Thanks to Alessandro Iurlano for reporting this issue after spotting it in
collectd <http://collectd.org>.
patch by Sebastian Harl
git-svn-id: svn://svn.oetiker.ch/rrdtool/branches/1.3/program@1753 a5681a0c-68f1-0310-ab6d-d61299d08faa
configure.ac | patch | blob | history | |
src/rrd_thread_safe.c | patch | blob | history |
diff --git a/configure.ac b/configure.ac
index 322b03b26c243dba52efe84eef040fdd47e34e6b..fba4862ea1d660bb68ac271ecaaf733533848ec6 100644 (file)
--- a/configure.ac
+++ b/configure.ac
dnl for each function found we get a definition in config.h
dnl of the form HAVE_FUNCTION
-AC_CHECK_FUNCS(tzset fsync mbstowcs opendir readdir chdir chroot getuid setlocale strerror strerror_r snprintf vsnprintf fpclass class fp_class isnan memmove strchr mktime getrusage gettimeofday)
+AC_CHECK_FUNCS(tzset fsync mbstowcs opendir readdir chdir chroot getuid setlocale strerror snprintf vsnprintf fpclass class fp_class isnan memmove strchr mktime getrusage gettimeofday)
+
+AC_FUNC_STRERROR_R
CONFIGURE_PART(Map/Fadvis/Madvise checking)
diff --git a/src/rrd_thread_safe.c b/src/rrd_thread_safe.c
index 14b891101e7bf02171094e882180f597d0cb33ef..9aa4599e861e9f96e3468e7808f49b636b3d556f 100644 (file)
--- a/src/rrd_thread_safe.c
+++ b/src/rrd_thread_safe.c
int err)
{
rrd_context_t *ctx = rrd_get_context();
+ char *ret = "unknown error";
- if (strerror_r(err, ctx->lib_errstr, sizeof(ctx->lib_errstr)))
- return "strerror_r failed. sorry!";
- else
- return ctx->lib_errstr;
+ *ctx->lib_errstr = '\0';
+
+ /* Even though POSIX/XSI requires "strerror_r" to return an "int", some
+ * systems (e.g. the GNU libc) return a "char *" _and_ ignore the second
+ * argument ... -tokkee */
+#if STRERROR_R_CHAR_P
+ ret = strerror_r(err, ctx->lib_errstr, sizeof(ctx->lib_errstr));
+ if ((! ret) || (*ret == '\0')) {
+ if (*ctx->lib_errstr != '\0')
+ ret = ctx->lib_errstr;
+ else {
+ /* according to the manpage this should not happen -
+ let's handle it somehow sanely anyway */
+ snprintf(ctx->lib_errstr, sizeof(ctx->lib_errstr),
+ "unknown error %i - strerror_r did not return anything",
+ err);
+ ctx->lib_errstr[sizeof(ctx->lib_errstr) - 1] = '\0';
+ ret = ctx->lib_errstr;
+ }
+ }
+#else /* ! STRERROR_R_CHAR_P */
+ if (strerror_r(err, ctx->lib_errstr, sizeof(ctx->lib_errstr))) {
+ snprintf(ctx->lib_errstr, sizeof(ctx->lib_errstr),
+ "unknown error %i - strerror_r returned with errno = %i",
+ err, errno);
+ ctx->lib_errstr[sizeof(ctx->lib_errstr) - 1] = '\0';
+ }
+ ret = ctx->lib_errstr;
+#endif
+ return ret;
}
#else
#undef strerror