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 -- [email protected]
To unsubscribe send an email to [email protected]