Distinguish between the XSI-compliant and the GNU-specific version of `strerror_r ()`
authorcherusker <prince.cherusker@gmail.com>
Mon, 7 Aug 2017 12:12:53 +0000 (14:12 +0200)
committercherusker <prince.cherusker@gmail.com>
Thu, 10 Aug 2017 16:47:08 +0000 (18:47 +0200)
- add USE_STRERROR_R_XSI to use the feature test macros conveniently later
- deal with the GNU-specific version of `strerror_r ()` separately (leave the code for the XSI-compliant version untouched)
- make `buff_len` size_t as this is ISO compliant (even though it should not really matter in this case)

mono/eglib/gstr.c

index 98d8faf2679e9822d47a3831b32f3160d766a194..cd2fda3c2a115f0fe3a04526d31719d90e0e8e84 100644 (file)
 
 #include <errno.h>
 
+/*
+ *  Linux knows two different versions of strerror_r () that can only be distinguished
+ *  by using feature test macros.  Please check the man pages for more details.
+ */
+#if defined (_POSIX_C_SOURCE) && defined (_GNU_SOURCE)
+#if (_POSIX_C_SOURCE >= 200112L) && !_GNU_SOURCE
+#define USE_STRERROR_R_XSI
+#endif
+#endif
+
 /* 
  * g_strndup and g_vasprintf need to allocate memory with g_malloc if 
  * ENABLE_OVERRIDABLE_ALLOCATORS is defined so that it can be safely freed with g_free 
@@ -231,10 +241,11 @@ g_strerror (gint errnum)
 #ifdef HAVE_STRERROR_R
                char tmp_buff [128]; //Quite arbitrary, should be large enough
                char *buff = tmp_buff;
-               int buff_len = sizeof (tmp_buff);
-               int r;
+               size_t buff_len = sizeof (tmp_buff);
                buff [0] = 0;
 
+#ifdef USE_STRERROR_R_XSI
+               int r;
                while ((r = strerror_r (errnum, buff, buff_len - 1))) {
                        if (r != ERANGE) {
                                buff = g_strdup_printf ("Invalid Error code '%d'", errnum);
@@ -251,10 +262,16 @@ g_strerror (gint errnum)
                        error_messages [errnum] = g_strdup (buff);
                if (buff != tmp_buff)
                        g_free (buff);
-#else
+#else /* USE_STRERROR_R_XSI */
+               buff = strerror_r (errnum, buff, buff_len);
+               if (!error_messages [errnum])
+                       error_messages [errnum] = g_strdup (buff);
+#endif /* USE_STRERROR_R_XSI */
+
+#else /* HAVE_STRERROR_R */
                if (!error_messages [errnum])
                        error_messages [errnum] = g_strdup_printf ("Error code '%d'", errnum);
-#endif
+#endif /* HAVE_STRERROR_R */
 
 
 #ifndef G_OS_WIN32