]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
FreeSWITCH: Add switch_strerror_r() to fix problems with XSI and GNU variants of...
authorStefan Knoblich <stkn@openisdn.net>
Tue, 14 Aug 2012 12:11:44 +0000 (14:11 +0200)
committerStefan Knoblich <stkn@openisdn.net>
Tue, 14 Aug 2012 12:11:44 +0000 (14:11 +0200)
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>
configure.in
src/include/switch_utils.h
src/switch_rtp.c
src/switch_utils.c

index 0345dd208c675e6cd3c5a1f9f672a0d92a0b5543..87d868b7a0537e7722768eadd6f54a3651c9a1b0 100644 (file)
@@ -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()])])
index 40560a043429b18e228fe4d43b9b56665627bd12..6b1824a15321d583a0934bc884d8a25b36ad2d97 100644 (file)
@@ -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:
index f0749d80873c7890ca7292896cfc990c56fc4080..1c23efc714380d9cc5ff99166b81799200259bc4 100644 (file)
@@ -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;
                        }
index 157ce177f207fb52e978980c9b9638cef348e527..b0c4e1a287226b9f4036e4689bb52ddd926d6474 100644 (file)
@@ -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