GNU variant of strerror_r() returns char *, while the XSI version returns int.
To make things worse, glibc ships both and added a unused result warning
in recent versions (2.16) causing the build to fail.
Add our own custom wrapper that always returns a pointer to the message buffer
and additionally make XSI versions of strerror_r() GNU compatible by
returning "Unknown error xxx" if no error message is available.
Fixes:
src/switch_rtp.c: In function 'rtp_common_read':
src/switch_rtp.c:3313:15: error: ignoring return value of 'strerror_r',
declared with attribute warn_unused_result [-Werror=unused-result]
cc1: all warnings being treated as errors
Signed-off-by: Stefan Knoblich <stkn@openisdn.net>
AC_CHECK_FUNCS([sched_setscheduler setpriority setrlimit setgroups initgroups])
AC_CHECK_FUNCS([wcsncmp setgroups asprintf setenv pselect gettimeofday localtime_r gmtime_r strcasecmp stricmp _stricmp])
+# Check availability and return type of strerror_r
+# (NOTE: apr-1-config sets -D_GNU_SOURCE at build-time, need to run the check with it too)
+save_CPPFLAGS="$CPPFLAGS"
+CPPFLAGS="$CPPFLAGS -D_GNU_SOURCE"
+AC_FUNC_STRERROR_R
+CPPFLAGS="$save_CPPFLAGS"
+
AX_HAVE_CPU_SET
AC_CHECK_LIB(rt, clock_gettime, [AC_DEFINE(HAVE_CLOCK_GETTIME, 1, [Define if you have clock_gettime()])])
SWITCH_DECLARE(unsigned int) switch_atoui(const char *nptr);
SWITCH_DECLARE(unsigned long) switch_atoul(const char *nptr);
+/**
+ * Portable version of strerror_r(), work around for the incompatible
+ * return type of GNU and XSI variants.
+ * \param[in] errnum Error number
+ * \param[both] buf Buffer for error message
+ * \param[in] buflen Size of message buffer
+ * \return Pointer to message buffer, returning error message or "Unknown error xxx" if none found
+ */
+SWITCH_DECLARE(char *) switch_strerror_r(int errnum, char *buf, switch_size_t buflen);
+
SWITCH_END_EXTERN_C
#endif
/* For Emacs:
if (!SWITCH_STATUS_IS_BREAK(poll_status) && poll_status != SWITCH_STATUS_TIMEOUT) {
char tmp[128] = "";
- strerror_r(poll_status, tmp, sizeof(tmp));
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Poll failed with error: %d [%s]\n", poll_status, tmp);
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Poll failed with error: %d [%s]\n",
+ poll_status, switch_strerror_r(poll_status, tmp, sizeof(tmp)));
ret = -1;
goto end;
}
else return (unsigned long) tmp;
}
+
+SWITCH_DECLARE(char *) switch_strerror_r(int errnum, char *buf, switch_size_t buflen)
+{
+#ifdef HAVE_STRERROR_R
+#ifdef STRERROR_R_CHAR_P
+ /* GNU variant returning char *, avoids warn-unused-result error */
+ return strerror_r(errnum, buf, buflen);
+#else
+ /*
+ * XSI variant returning int, with GNU compatible error string,
+ * if no message could be found
+ */
+ if (strerror_r(errnum, buf, buflen)) {
+ switch_snprintf(buf, buflen, "Unknown error %d", errnum);
+ }
+ return buf;
+#endif /* STRERROR_R_CHAR_P */
+#else
+ /* Fallback, copy string into private buffer */
+ switch_copy_string(buf, strerror(errnum), buflen);
+ return buf;
+#endif
+}
+
+
/* For Emacs:
* Local Variables:
* mode:c