Kenta Murata 2021-07-14 15:51:26 +09:00 коммит произвёл Nobuyoshi Nakada
Родитель 169529a0c0
Коммит 67897762cf
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 7CD2805BFA3770C6
4 изменённых файлов: 57 добавлений и 1 удалений

Просмотреть файл

@ -187,6 +187,7 @@ else
end
have_header 'sys/mman.h'
have_header 'link.h'
if have_header "dlfcn.h"
have_library "dl"
@ -196,8 +197,10 @@ if have_header "dlfcn.h"
end
have_func "dlerror"
have_func "dlinfo"
have_const("RTLD_DI_LINKMAP", "dlfcn.h")
elsif have_header "windows.h"
%w{ LoadLibrary FreeLibrary GetProcAddress }.each do |func|
%w{ LoadLibrary FreeLibrary GetProcAddress GetModuleFileName }.each do |func|
abort "missing function #{func}" unless have_func(func)
end

Просмотреть файл

@ -12,6 +12,10 @@
#include <sys/mman.h>
#endif
#if defined(HAVE_LINK_H)
# include <link.h>
#endif
#if defined(HAVE_DLFCN_H)
# include <dlfcn.h>
# /* some stranger systems may not define all of these */

Просмотреть файл

@ -386,6 +386,48 @@ fiddle_handle_sym(void *handle, VALUE symbol)
return PTR2NUM(func);
}
/*
* call-seq: file_name
*
* Returns the file name of this handle.
*/
static VALUE
rb_fiddle_handle_file_name(VALUE self)
{
struct dl_handle *fiddle_handle;
TypedData_Get_Struct(self, struct dl_handle, &fiddle_handle_data_type, fiddle_handle);
#if defined(HAVE_DLINFO) && defined(HAVE_CONST_RTLD_DI_LINKMAP)
{
struct link_map *lm = NULL;
int res = dlinfo(fiddle_handle->ptr, RTLD_DI_LINKMAP, &lm);
if (res == 0 && lm != NULL) {
return rb_str_new_cstr(lm->l_name);
}
else {
#if defined(HAVE_DLERROR)
rb_raise(rb_eFiddleDLError, "could not get handle file name: %s", dlerror());
#else
rb_raise(rb_eFiddleDLError, "could not get handle file name");
#endif
}
}
#elif defined(HAVE_GETMODULEFILENAME)
{
char filename[MAX_PATH];
DWORD res = GetModuleFileName(fiddle_handle->ptr, filename, MAX_PATH);
if (res == 0) {
rb_raise(rb_eFiddleDLError, "could not get handle file name: %s", dlerror());
}
return rb_str_new_cstr(filename);
}
#else
(void)fiddle_handle;
return Qnil;
#endif
}
void
Init_fiddle_handle(void)
{
@ -484,6 +526,7 @@ Init_fiddle_handle(void)
rb_define_method(rb_cHandle, "close", rb_fiddle_handle_close, 0);
rb_define_method(rb_cHandle, "sym", rb_fiddle_handle_sym, 1);
rb_define_method(rb_cHandle, "[]", rb_fiddle_handle_sym, 1);
rb_define_method(rb_cHandle, "file_name", rb_fiddle_handle_file_name, 0);
rb_define_method(rb_cHandle, "disable_close", rb_fiddle_handle_disable_close, 0);
rb_define_method(rb_cHandle, "enable_close", rb_fiddle_handle_enable_close, 0);
rb_define_method(rb_cHandle, "close_enabled?", rb_fiddle_handle_close_enabled_p, 0);

Просмотреть файл

@ -112,6 +112,12 @@ module Fiddle
assert !handle.close_enabled?, 'close is enabled'
end
def test_file_name
handle = Handle.new(LIBC_SO)
assert_kind_of String, handle.file_name
assert_equal File.basename(handle.file_name), File.basename(LIBC_SO)
end unless /darwin/ =~ RUBY_PLATFORM
def test_NEXT
begin
# Linux / Darwin