Changeset: 51f505078dfd for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/51f505078dfd
Modified Files:
        cmake/monetdb-defines.cmake
        common/stream/stream.c
        gdk/gdk_posix.c
        gdk/gdk_posix.h
        monetdb_config.h.in
Branch: Aug2024
Log Message:

Try to properly distinguish between two forms of strerror_r.
But use strerror_s if available.


diffs (131 lines):

diff --git a/cmake/monetdb-defines.cmake b/cmake/monetdb-defines.cmake
--- a/cmake/monetdb-defines.cmake
+++ b/cmake/monetdb-defines.cmake
@@ -84,6 +84,7 @@ function(monetdb_configure_defines)
   check_function_exists("getuid" HAVE_GETUID)
   check_symbol_exists("gmtime_r" "time.h" HAVE_GMTIME_R)
   check_symbol_exists("localtime_r" "time.h" HAVE_LOCALTIME_R)
+  check_symbol_exists("strerror_s" "string.h" HAVE_STRERROR_S)
   check_symbol_exists("strerror_r" "string.h" HAVE_STRERROR_R)
   check_function_exists("lockf" HAVE_LOCKF)
   check_symbol_exists("madvise" "sys/mman.h" HAVE_MADVISE)
diff --git a/common/stream/stream.c b/common/stream/stream.c
--- a/common/stream/stream.c
+++ b/common/stream/stream.c
@@ -426,24 +426,32 @@ mnstr_set_open_error(const char *name, i
 static size_t
 my_strerror_r(int error_nr, char *buf, size_t buflen)
 {
-       // Three cases:
-       // 1. no strerror_r
+       // Four cases:
+       // 1. strerror_s
        // 2. gnu strerror_r (returns char* and does not always fill buffer)
        // 3. xsi strerror_r (returns int and always fills the buffer)
+       // 4. no strerror_r and no strerror_s
        char *to_move;
-#ifndef HAVE_STRERROR_R
-       // Hope for the best
-       to_move = strerror(error_nr);
-#elif !defined(_GNU_SOURCE) || !_GNU_SOURCE
-       // standard strerror_r always writes to buf
+#ifdef HAVE_STRERROR_S
+       int result_code = strerror_s(buf, buflen, error_nr);
+       if (result_code == 0)
+               to_move = NULL;
+       else
+               to_move = "<failed to retrieve error message>";
+#elif defined(HAVE_STRERROR_R)
+#ifdef STRERROR_R_CHARP
+       // gnu strerror_r sometimes only returns static string, needs copy
+       to_move = strerror_r(error_nr, buf, buflen);
+#else
        int result_code = strerror_r(error_nr, buf, buflen);
        if (result_code == 0)
                to_move = NULL;
        else
                to_move = "<failed to retrieve error message>";
+#endif
 #else
-       // gnu strerror_r sometimes only returns static string, needs copy
-       to_move = strerror_r(error_nr, buf, buflen);
+       // Hope for the best
+       to_move = strerror(error_nr);
 #endif
        if (to_move != NULL) {
                // move to buffer
diff --git a/gdk/gdk_posix.c b/gdk/gdk_posix.c
--- a/gdk/gdk_posix.c
+++ b/gdk/gdk_posix.c
@@ -1013,7 +1013,7 @@ ctime_r(const time_t *restrict t, char *
 }
 #endif
 
-#ifndef HAVE_STRERROR_R
+#if !defined(HAVE_STRERROR_R) && !defined(HAVE_STRERROR_S)
 static MT_Lock strerrlock = MT_LOCK_INITIALIZER(strerrlock);
 
 int
diff --git a/gdk/gdk_posix.h b/gdk/gdk_posix.h
--- a/gdk/gdk_posix.h
+++ b/gdk/gdk_posix.h
@@ -175,20 +175,25 @@ gdk_export char *asctime_r(const struct 
 #ifndef HAVE_CTIME_R
 gdk_export char *ctime_r(const time_t *restrict, char *restrict);
 #endif
-#ifndef HAVE_STRERROR_R
+#if !defined(HAVE_STRERROR_R) && !defined(HAVE_STRERROR_S)
 gdk_export int strerror_r(int errnum, char *buf, size_t buflen);
 #endif
 
 static inline const char *
 GDKstrerror(int errnum, char *buf, size_t buflen)
 {
-#if !defined(_GNU_SOURCE) || ((_POSIX_C_SOURCE >= 200112L) && !_GNU_SOURCE)
+#ifdef HAVE_STRERROR_S
+       if (strerror_s(buf, buflen, errnum) == 0)
+               return buf;
+       snprintf(buf, buflen, "Unknown error %d", errnum);
+       return buf;
+#elif defined(STRERROR_R_CHARP)
+       return strerror_r(errnum, buf, buflen);
+#else
        if (strerror_r(errnum, buf, buflen) == 0)
                return buf;
        snprintf(buf, buflen, "Unknown error %d", errnum);
        return buf;
-#else
-       return strerror_r(errnum, buf, buflen);
 #endif
 }
 
diff --git a/monetdb_config.h.in b/monetdb_config.h.in
--- a/monetdb_config.h.in
+++ b/monetdb_config.h.in
@@ -138,6 +138,7 @@
 #cmakedefine HAVE_GETUID 1
 #cmakedefine HAVE_GMTIME_R 1
 #cmakedefine HAVE_LOCALTIME_R 1
+#cmakedefine HAVE_STRERROR_S 1
 #cmakedefine HAVE_STRERROR_R 1
 #cmakedefine HAVE_LOCKF 1
 #cmakedefine HAVE_MADVISE  1
@@ -367,6 +368,18 @@ typedef __uint128_t uhge;
 #include <strings.h>           /* strcasecmp */
 #endif
 
+/* The GNU C library has two variants of strerror_r, the XSI compliant
+ * one which returns int and a GNU specific one which returns char *.
+ * According to the manual, we should check for _GNU_SOURCE to find out
+ * which is used (if defined, it's the char * version), but MUSL C (used
+ * on Alpine Linux) also defined _GNU_SOURCE but only defines the int
+ * version, so that won't fly.  Instead we look at __USE_GNU which only
+ * the GNU library defines (if _GNU_SOURCE is defined) and is the one
+ * actually used in the GNU header file to make the distinction. */
+#if defined(__USE_GNU) && defined(HAVE_STRERROR_R)
+#define STRERROR_R_CHARP 1
+#endif
+
 #ifdef _MSC_VER
 
 #define strdup(s)      _strdup(s)
_______________________________________________
checkin-list mailing list -- checkin-list@monetdb.org
To unsubscribe send an email to checkin-list-le...@monetdb.org

Reply via email to