From 34cf45ab19f0d4ec3f42ec414173aeb5fe0164b0 Mon Sep 17 00:00:00 2001 From: nobu Date: Sat, 23 May 2009 12:49:00 +0000 Subject: * 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 --- ext/dl/handle.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 46 insertions(+), 10 deletions(-) (limited to 'ext') 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); -- cgit v1.2.3