diff --git a/dln.c b/dln.c index ca520acd06..1009f7806f 100644 --- a/dln.c +++ b/dln.c @@ -194,7 +194,6 @@ dln_strerror(char *message, size_t size) } return message; } -#define dln_strerror() dln_strerror(message, sizeof message) #elif defined USE_DLN_DLOPEN static const char * dln_strerror(void) @@ -340,14 +339,12 @@ dln_disable_dlclose(void) #if defined(_WIN32) || defined(USE_DLN_DLOPEN) void * -dln_open(const char *file, const char **error) +dln_open(const char *file, char *error, size_t size) { static const char incompatible[] = "incompatible library version"; void *handle; #if defined(_WIN32) - char message[1024]; - /* Convert the file path to wide char */ WCHAR *winfile = rb_w32_mbstr_to_wstr(CP_UTF8, file, -1, NULL); if (!winfile) { @@ -359,14 +356,14 @@ dln_open(const char *file, const char **error) free(winfile); if (!handle) { - *error = dln_strerror(); + strlcpy(error, dln_strerror(error, size), size); return NULL; } # if defined(RUBY_EXPORT) if (!rb_w32_check_imported(handle, rb_libruby_handle())) { FreeLibrary(handle); - *error = incompatible; + strlcpy(error, incompatible, size); return NULL; } # endif @@ -386,7 +383,7 @@ dln_open(const char *file, const char **error) /* Load file */ handle = dlopen(file, RTLD_LAZY|RTLD_GLOBAL); if (handle == NULL) { - *error = dln_strerror(); + strlcpy(error, dln_strerror(), size); return NULL; } @@ -409,10 +406,14 @@ dln_open(const char *file, const char **error) libruby_name = tmp; } dlclose(handle); + if (libruby_name) { - dln_loaderror("linked to incompatible %s - %s", libruby_name, file); + snprintf(error, size, "linked to incompatible %s - %s", libruby_name, file); } - *error = incompatible; + else { + strlcpy(error, incompatible, size); + } + return NULL; } } @@ -442,7 +443,7 @@ dln_sym_func(void *handle, const char *symbol) const char *error; #if defined(_WIN32) char message[1024]; - error = dln_strerror(); + error = dln_strerror(message, sizeof(message)); #elif defined(USE_DLN_DLOPEN) const size_t errlen = strlen(error = dln_strerror()) + 1; error = memcpy(ALLOCA_N(char, errlen), error, errlen); @@ -497,8 +498,8 @@ void * dln_load(const char *file) { #if defined(_WIN32) || defined(USE_DLN_DLOPEN) - const char *error = NULL; - void *handle = dln_open(file, &error); + char error[1024]; + void *handle = dln_open(file, error, sizeof(error)); if (handle == NULL) { dln_loaderror("%s - %s", error, file); diff --git a/dln.h b/dln.h index 0bbbc73378..25cd946acf 100644 --- a/dln.h +++ b/dln.h @@ -25,7 +25,7 @@ RUBY_SYMBOL_EXPORT_BEGIN char *dln_find_exe_r(const char*,const char*,char*,size_t DLN_FIND_EXTRA_ARG_DECL); char *dln_find_file_r(const char*,const char*,char*,size_t DLN_FIND_EXTRA_ARG_DECL); void *dln_load(const char*); -void *dln_open(const char *file, const char **error); +void *dln_open(const char *file, char *error, size_t size); void *dln_symbol(void*,const char*); RUBY_SYMBOL_EXPORT_END diff --git a/dmydln.c b/dmydln.c index 70fd2c1d6c..4b73adc763 100644 --- a/dmydln.c +++ b/dmydln.c @@ -21,9 +21,9 @@ dln_symbol(void *handle, const char *symbol) UNREACHABLE_RETURN(NULL); } -NORETURN(void *dln_open(const char *library, const char **error)); +NORETURN(void *dln_open(const char *library, char *error, size_t size)); void* -dln_open(const char *library, const char **error) +dln_open(const char *library, char *error, size_t size) { rb_loaderror("this executable file can't load extension libraries"); diff --git a/gc.c b/gc.c index 79393e48d2..7d70a157e0 100644 --- a/gc.c +++ b/gc.c @@ -1896,8 +1896,8 @@ ruby_external_gc_init() char *gc_so_path = getenv("RUBY_GC_LIBRARY_PATH"); void *handle = NULL; if (gc_so_path) { - const char *error = NULL; - handle = dln_open(gc_so_path, &error); + char error[128]; + handle = dln_open(gc_so_path, error, sizeof(error)); if (!handle) { rb_bug("ruby_external_gc_init: Shared library %s cannot be opened (%s)", gc_so_path, error); }