[前][次][番号順一覧][スレッド一覧]

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/

[前][次][番号順一覧][スレッド一覧]