diff --git a/configure.in b/configure.in index 0345dd208c..87d868b7a0 100644 --- a/configure.in +++ b/configure.in @@ -495,6 +495,13 @@ AC_CHECK_FUNCS([gethostname vasprintf mmap mlock mlockall usleep getifaddrs time 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()])]) diff --git a/src/include/switch_utils.h b/src/include/switch_utils.h index 40560a0434..6b1824a153 100644 --- a/src/include/switch_utils.h +++ b/src/include/switch_utils.h @@ -837,6 +837,16 @@ SWITCH_DECLARE(char *) switch_format_number(const char *num); 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: diff --git a/src/switch_rtp.c b/src/switch_rtp.c index f0749d8087..1c23efc714 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -3310,8 +3310,8 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_ 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; } diff --git a/src/switch_utils.c b/src/switch_utils.c index 157ce177f2..b0c4e1a287 100644 --- a/src/switch_utils.c +++ b/src/switch_utils.c @@ -2968,6 +2968,31 @@ SWITCH_DECLARE(unsigned long) switch_atoul(const char *nptr) 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