aboutsummaryrefslogtreecommitdiffstats
path: root/dln.c
diff options
context:
space:
mode:
authorPeter Zhu <peter@peterzhu.ca>2022-01-19 09:00:33 -0500
committerPeter Zhu <peter@peterzhu.ca>2022-01-19 09:55:09 -0500
commit5c4734d1eff9322f9f21d9c21577978ab6e0d044 (patch)
tree1ac2ab912b0104d2b3f7631613d666e1be75ccab /dln.c
parent374904b25f0cd399b800d9b822659fbff382b23c (diff)
downloadruby-5c4734d1eff9322f9f21d9c21577978ab6e0d044.tar.gz
Refactor dln_load into dln_open and dln_sym
Refactor dln_load into dln_open and dln_sym to simplify the code for Windows and platforms that have dlopen.
Diffstat (limited to 'dln.c')
-rw-r--r--dln.c157
1 files changed, 81 insertions, 76 deletions
diff --git a/dln.c b/dln.c
index d3d5e38c3a..9e9632ef0c 100644
--- a/dln.c
+++ b/dln.c
@@ -279,28 +279,19 @@ dln_incompatible_library_p(void *handle)
COMPILER_WARNING_POP
#endif
-void*
-dln_load(const char *file)
+#if defined(_WIN32) || defined(USE_DLN_DLOPEN)
+static void *
+dln_open(const char *file)
{
-#if (defined _WIN32 || defined USE_DLN_DLOPEN) && defined RUBY_EXPORT
static const char incompatible[] = "incompatible library version";
-#endif
-#if defined _WIN32 || defined USE_DLN_DLOPEN
- const char *error = 0;
-#endif
+ const char *error = NULL;
+ void *handle;
-#if defined _WIN32
- HINSTANCE handle;
- WCHAR *winfile;
+#if defined(_WIN32)
char message[1024];
- void (*init_fct)(void);
- char *buf;
-
- /* Load the file as an object one */
- init_funcname(&buf, file);
/* Convert the file path to wide char */
- winfile = rb_w32_mbstr_to_wstr(CP_UTF8, file, -1, NULL);
+ WCHAR *winfile = rb_w32_mbstr_to_wstr(CP_UTF8, file, -1, NULL);
if (!winfile) {
dln_memerror();
}
@@ -314,82 +305,104 @@ dln_load(const char *file)
goto failed;
}
-#if defined _WIN32 && defined RUBY_EXPORT
+# if defined(RUBY_EXPORT)
if (!rb_w32_check_imported(handle, rb_libruby_handle())) {
FreeLibrary(handle);
error = incompatible;
goto failed;
}
-#endif
-
- if ((init_fct = (void(*)(void))GetProcAddress(handle, buf)) == NULL) {
- dln_loaderror("%s - %s\n%s", dln_strerror(), buf, file);
- }
+# endif
- /* Call the init code */
- (*init_fct)();
- return handle;
-#else
- char *buf;
- /* Load the file as an object one */
- init_funcname(&buf, file);
- translit_separator(file);
+#elif defined(USE_DLN_DLOPEN)
-#ifdef USE_DLN_DLOPEN
-#define DLN_DEFINED
- {
- void *handle;
- void (*init_fct)(void);
+# ifndef RTLD_LAZY
+# define RTLD_LAZY 1
+# endif
+# ifdef __INTERIX
+# undef RTLD_GLOBAL
+# endif
+# ifndef RTLD_GLOBAL
+# define RTLD_GLOBAL 0
+# endif
-#ifndef RTLD_LAZY
-# define RTLD_LAZY 1
-#endif
-#ifdef __INTERIX
-# undef RTLD_GLOBAL
-#endif
-#ifndef RTLD_GLOBAL
-# define RTLD_GLOBAL 0
-#endif
+ /* Load file */
+ handle = dlopen(file, RTLD_LAZY|RTLD_GLOBAL);
+ if (handle == NULL) {
+ error = dln_strerror();
+ goto failed;
+ }
- /* Load file */
- if ((handle = (void*)dlopen(file, RTLD_LAZY|RTLD_GLOBAL)) == NULL) {
- error = dln_strerror();
- goto failed;
- }
-# if defined RUBY_EXPORT
+# if defined(RUBY_EXPORT)
{
if (dln_incompatible_library_p(handle)) {
-
-# if defined __APPLE__ && \
+# if defined(__APPLE__) && \
defined(MAC_OS_X_VERSION_MIN_REQUIRED) && \
(MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_11)
/* dlclose() segfaults */
rb_fatal("%s - %s", incompatible, file);
-# else
+# else
dlclose(handle);
error = incompatible;
goto failed;
-# endif
+# endif
}
}
# endif
+#endif
- init_fct = (void(*)(void))(VALUE)dlsym(handle, buf);
- if (init_fct == NULL) {
- const size_t errlen = strlen(error = dln_strerror()) + 1;
- error = memcpy(ALLOCA_N(char, errlen), error, errlen);
- dlclose(handle);
- goto failed;
- }
- /* Call the init code */
- (*init_fct)();
+ return handle;
- return handle;
+ failed:
+ dln_loaderror("%s - %s", error, file);
+}
+
+static void *
+dln_sym(void *handle, const char *symbol)
+{
+ void *func;
+ const char *error;
+
+#if defined(_WIN32)
+ char message[1024];
+
+ func = GetProcAddress(handle, symbol);
+ if (func == NULL) {
+ error = dln_strerror();
+ goto failed;
}
-#endif /* USE_DLN_DLOPEN */
-#if defined(_AIX)
-#define DLN_DEFINED
+#elif defined(USE_DLN_DLOPEN)
+ func = dlsym(handle, symbol);
+ if (func == NULL) {
+ const size_t errlen = strlen(error = dln_strerror()) + 1;
+ error = memcpy(ALLOCA_N(char, errlen), error, errlen);
+ goto failed;
+ }
+#endif
+
+ return func;
+
+ failed:
+ dln_loaderror("%s - %s", error, symbol);
+}
+#endif
+
+void *
+dln_load(const char *file)
+{
+#if defined(_WIN32) || defined(USE_DLN_DLOPEN)
+ void *handle = dln_open(file);
+
+ char *init_fct_name;
+ init_funcname(&init_fct_name, file);
+ void (*init_fct)(void) = (void(*)(void))dln_sym(handle, init_fct_name);
+
+ /* Call the init code */
+ (*init_fct)();
+
+ return handle;
+
+#elif defined(_AIX)
{
void (*init_fct)(void);
@@ -403,17 +416,9 @@ dln_load(const char *file)
(*init_fct)();
return (void*)init_fct;
}
-#endif /* _AIX */
-
-#ifndef DLN_DEFINED
+#else
dln_notimplement();
#endif
-#endif
-#if defined(_WIN32) || defined(USE_DLN_DLOPEN)
- failed:
- dln_loaderror("%s - %s", error, file);
-#endif
-
return 0; /* dummy return */
}