ruby-changes:66784
From: Kenta <ko1@a...>
Date: Wed, 14 Jul 2021 19:00:38 +0900 (JST)
Subject: [ruby-changes:66784] 67897762cf (master): [ruby/fiddle] Add Fiddle::Handle#file_name (https://github.com/ruby/fiddle/pull/88)
https://git.ruby-lang.org/ruby.git/commit/?id=67897762cf From 67897762cf3cabad99effd636b50a2db26fb0f3f Mon Sep 17 00:00:00 2001 From: Kenta Murata <mrkn@u...> Date: Wed, 14 Jul 2021 15:51:26 +0900 Subject: [ruby/fiddle] Add Fiddle::Handle#file_name (https://github.com/ruby/fiddle/pull/88) https://github.com/ruby/fiddle/commit/4ee1c6fc4b --- ext/fiddle/extconf.rb | 5 ++++- ext/fiddle/fiddle.h | 4 ++++ ext/fiddle/handle.c | 43 +++++++++++++++++++++++++++++++++++++++++++ test/fiddle/test_handle.rb | 6 ++++++ 4 files changed, 57 insertions(+), 1 deletion(-) diff --git a/ext/fiddle/extconf.rb b/ext/fiddle/extconf.rb index 8cc98fb..053456d 100644 --- a/ext/fiddle/extconf.rb +++ b/ext/fiddle/extconf.rb @@ -187,6 +187,7 @@ else https://github.com/ruby/ruby/blob/trunk/ext/fiddle/extconf.rb#L187 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" https://github.com/ruby/ruby/blob/trunk/ext/fiddle/extconf.rb#L197 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 diff --git a/ext/fiddle/fiddle.h b/ext/fiddle/fiddle.h index bf97b59..9de62a5 100644 --- a/ext/fiddle/fiddle.h +++ b/ext/fiddle/fiddle.h @@ -12,6 +12,10 @@ https://github.com/ruby/ruby/blob/trunk/ext/fiddle/fiddle.h#L12 #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 */ diff --git a/ext/fiddle/handle.c b/ext/fiddle/handle.c index a4a32f1..76b9090 100644 --- a/ext/fiddle/handle.c +++ b/ext/fiddle/handle.c @@ -386,6 +386,48 @@ fiddle_handle_sym(void *handle, VALUE symbol) https://github.com/ruby/ruby/blob/trunk/ext/fiddle/handle.c#L386 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) https://github.com/ruby/ruby/blob/trunk/ext/fiddle/handle.c#L526 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); diff --git a/test/fiddle/test_handle.rb b/test/fiddle/test_handle.rb index e89ad53..5c15173 100644 --- a/test/fiddle/test_handle.rb +++ b/test/fiddle/test_handle.rb @@ -112,6 +112,12 @@ module Fiddle https://github.com/ruby/ruby/blob/trunk/test/fiddle/test_handle.rb#L112 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 -- cgit v1.1 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/