summaryrefslogtreecommitdiff
path: root/ext/dl/handle.c
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2009-05-23 12:49:00 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2009-05-23 12:49:00 +0000
commit34cf45ab19f0d4ec3f42ec414173aeb5fe0164b0 (patch)
tree1c698de2214dae8a130d3e0542cc4aad5ff44281 /ext/dl/handle.c
parent96e6cfb83507565e2b567b9f05742494af0fe778 (diff)
* ext/dl/handle.c (rb_dlhandle_s_sym): added a method to access
using RTLD_NEXT. [ruby-dev:38152] * ext/dl/handle.c (Init_dlhandle): added constants DEFAULT and NEXT which correspond to RTLD_DEFAULT and RTLD_NEXT. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@23551 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'ext/dl/handle.c')
-rw-r--r--ext/dl/handle.c56
1 files changed, 46 insertions, 10 deletions
diff --git a/ext/dl/handle.c b/ext/dl/handle.c
index ef02124e6f..14a5299223 100644
--- a/ext/dl/handle.c
+++ b/ext/dl/handle.c
@@ -64,6 +64,18 @@ rb_dlhandle_s_allocate(VALUE klass)
return obj;
}
+static VALUE
+predefined_dlhandle(void *handle)
+{
+ VALUE obj = rb_dlhandle_s_allocate(rb_cDLHandle);
+ struct dl_handle *dlhandle = DATA_PTR(obj);
+
+ dlhandle->ptr = handle;
+ dlhandle->open = 1;
+ OBJ_FREEZE(obj);
+ return obj;
+}
+
VALUE
rb_dlhandle_initialize(int argc, VALUE argv[], VALUE self)
{
@@ -165,19 +177,13 @@ rb_dlhandle_to_i(VALUE self)
return PTR2NUM(dlhandle);
}
+static VALUE dlhandle_sym(void *handle, const char *symbol);
+
VALUE
rb_dlhandle_sym(VALUE self, VALUE sym)
{
- void (*func)();
struct dl_handle *dlhandle;
- void *handle;
const char *name;
-#if defined(HAVE_DLERROR)
- const char *err;
-# define CHECK_DLERROR if( err = dlerror() ){ func = 0; }
-#else
-# define CHECK_DLERROR
-#endif
rb_secure(2);
@@ -187,9 +193,35 @@ rb_dlhandle_sym(VALUE self, VALUE sym)
if( ! dlhandle->open ){
rb_raise(rb_eDLError, "closed handle");
}
- handle = dlhandle->ptr;
- func = dlsym(handle, name);
+ return dlhandle_sym(dlhandle->ptr, StringValueCStr(sym));
+}
+
+#ifndef RTLD_NEXT
+#define RTLD_NEXT NULL
+#endif
+#ifndef RTLD_DEFAULT
+#define RTLD_DEFAULT NULL
+#endif
+
+VALUE
+rb_dlhandle_s_sym(VALUE self, VALUE sym)
+{
+ rb_secure(2);
+ return dlhandle_sym(RTLD_NEXT, StringValueCStr(sym));
+}
+
+static VALUE
+dlhandle_sym(void *handle, const char *name)
+{
+#if defined(HAVE_DLERROR)
+ const char *err;
+# define CHECK_DLERROR if( err = dlerror() ){ func = 0; }
+#else
+# define CHECK_DLERROR
+#endif
+ void (*func)() = dlsym(handle, name);
+
CHECK_DLERROR;
#if defined(FUNC_STDCALL)
if( !func ){
@@ -244,6 +276,10 @@ Init_dlhandle(void)
{
rb_cDLHandle = rb_define_class_under(rb_mDL, "Handle", rb_cObject);
rb_define_alloc_func(rb_cDLHandle, rb_dlhandle_s_allocate);
+ rb_define_singleton_method(rb_cDLHandle, "sym", rb_dlhandle_s_sym, 1);
+ rb_define_singleton_method(rb_cDLHandle, "[]", rb_dlhandle_s_sym, 1);
+ rb_define_const(rb_cDLHandle, "NEXT", predefined_dlhandle(RTLD_NEXT));
+ rb_define_const(rb_cDLHandle, "DEFAULT", predefined_dlhandle(RTLD_DEFAULT));
rb_define_method(rb_cDLHandle, "initialize", rb_dlhandle_initialize, -1);
rb_define_method(rb_cDLHandle, "to_i", rb_dlhandle_to_i, 0);
rb_define_method(rb_cDLHandle, "close", rb_dlhandle_close, 0);