aboutsummaryrefslogtreecommitdiffstats
path: root/dln.c
diff options
context:
space:
mode:
authorNobuyoshi Nakada <nobu@ruby-lang.org>2022-02-17 17:35:38 +0900
committerNobuyoshi Nakada <nobu@ruby-lang.org>2022-02-17 20:29:50 +0900
commit5952a1f201cfed38277b4fafa0624c1a048edb6d (patch)
treed16f6ff4de9145994afb9f9f9354078e798f29bc /dln.c
parentc8b414b3345564d975445b25d9bcb9e2604f636d (diff)
downloadruby-5952a1f201cfed38277b4fafa0624c1a048edb6d.tar.gz
Check running macOS version at runtime
Diffstat (limited to 'dln.c')
-rw-r--r--dln.c35
1 files changed, 27 insertions, 8 deletions
diff --git a/dln.c b/dln.c
index 48bebb824b..5c1e6f8c02 100644
--- a/dln.c
+++ b/dln.c
@@ -15,11 +15,13 @@
#define dln_memerror rb_memerror
#define dln_exit rb_exit
#define dln_loaderror rb_loaderror
+#define dln_fatalerror rb_fatal
#else
#define dln_notimplement --->>> dln not implemented <<<---
#define dln_memerror abort
#define dln_exit exit
static void dln_loaderror(const char *format, ...);
+#define dln_fatalerror dln_loaderror
#endif
#include "dln.h"
#include "internal.h"
@@ -281,6 +283,24 @@ dln_incompatible_library_p(void *handle)
COMPILER_WARNING_POP
#endif
+#if defined(MAC_OS_X_VERSION_MIN_REQUIRED) && \
+ (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_11)
+# include <sys/sysctl.h>
+
+static bool
+dln_disable_dlclose(void)
+{
+ int mib[] = {CTL_KERN, KERN_OSREV};
+ int32_t rev;
+ size_t size = sizeof(rev);
+ if (sysctl(mib, numberof(mib), &rev, &size, NULL, 0)) return true;
+ if (rev < MAC_OS_X_VERSION_10_11) return true;
+ return false;
+}
+#else
+# define dln_disable_dlclose() false
+#endif
+
#if defined(_WIN32) || defined(USE_DLN_DLOPEN)
static void *
dln_open(const char *file)
@@ -335,20 +355,19 @@ dln_open(const char *file)
}
# if defined(RUBY_EXPORT)
- {
- if (dln_incompatible_library_p(handle)) {
-# if defined(__APPLE__) && \
- defined(MAC_OS_X_VERSION_MIN_REQUIRED) && \
- (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_11)
+ {
+ if (dln_incompatible_library_p(handle)) {
+ if (dln_disable_dlclose()) {
/* dlclose() segfaults */
- rb_fatal("%s - %s", incompatible, file);
-# else
+ dln_fatalerror("%s - %s", incompatible, file);
+ }
+ else {
dlclose(handle);
error = incompatible;
goto failed;
-# endif
}
}
+ }
# endif
#endif