From 0f8d55fa98c37fb2b0925620c10fd305f63acd84 Mon Sep 17 00:00:00 2001 From: ttate Date: Sat, 8 Nov 2003 04:48:35 +0000 Subject: Add DL.win32_last_error and DL.last_error. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@4922 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 4 ++++ ext/dl/extconf.rb | 10 +++++++-- ext/dl/sym.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 73 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 99c1c3d335..0ea4d62730 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +Sat Nov 8 13:28:46 2003 Takaaki Tateishi + * ext/dl/sym.c: Add DL.win32_last_error and DL.last_error. + Thanks, Kaoru Shirai. + Sat Nov 8 06:19:38 2003 Hidetoshi NAGAI * ext/tcltklib/tcltklib.c: To fix 'pthread-enabled Tcl/Tk' problem, diff --git a/ext/dl/extconf.rb b/ext/dl/extconf.rb index e712134448..beb15ab04c 100644 --- a/ext/dl/extconf.rb +++ b/ext/dl/extconf.rb @@ -127,6 +127,13 @@ if( $with_type_voidp ) $dlconfig_h << "#define WITH_TYPE_VOIDP\n" end +if( have_header("windows.h") ) + have_library("kernel32") + have_func("GetLastError", "windows.h") + dlc_define("HAVE_WINDOWS_H") + have_windows_h = true +end + if( have_header("dlfcn.h") ) dlc_define("HAVE_DLFCN_H") have_library("dl") @@ -136,8 +143,7 @@ if( have_header("dlfcn.h") ) if( have_func("dlerror") ) dlc_define("HAVE_DLERROR") end -elsif( have_header("windows.h") ) - dlc_define("HAVE_WINDOWS_H") +elsif ( have_windows_h ) have_func("LoadLibrary") have_func("FreeLibrary") have_func("GetProcAddress") diff --git a/ext/dl/sym.c b/ext/dl/sym.c index 4a2d736465..dc48f6ce95 100644 --- a/ext/dl/sym.c +++ b/ext/dl/sym.c @@ -3,6 +3,7 @@ */ #include +#include #include "dl.h" VALUE rb_cDLSymbol; @@ -316,6 +317,41 @@ stack_size(struct sym_data *sym) return size; } +static ID rb_dl_id_DLErrno; + +static VALUE +rb_dl_get_last_error(VALUE self) +{ + return rb_thread_local_aref(rb_thread_current(), rb_dl_id_DLErrno); +} + +static VALUE +rb_dl_set_last_error(VALUE self, VALUE val) +{ + errno = NUM2INT(val); + rb_thread_local_aset(rb_thread_current(), rb_dl_id_DLErrno, val); + return Qnil; +} + +#ifdef HAVE_WINDOWS_H +#include +static ID rb_dl_id_DLW32Error; + +static VALUE +rb_dl_win32_get_lasterror(VALUE self) +{ + return rb_thread_local_aref(rb_thread_current(), rb_dl_id_DLW32Error); +} + +static VALUE +rb_dl_win32_set_lasterror(VALUE self, VALUE val) +{ + SetLastError(NUM2INT(val)); + rb_thread_local_aset(rb_thread_current(), rb_dl_id_DLW32Error, val); + return Qnil; +} +#endif + VALUE rb_dlsym_call(int argc, VALUE argv[], VALUE self) { @@ -675,6 +711,22 @@ rb_dlsym_call(int argc, VALUE argv[], VALUE self) rb_raise(rb_eDLTypeError, "unknown type `%c'", sym->type[0]); } } + + { + /* + * We should get the value of errno/GetLastError() before calling another functions. + */ + int last_errno = errno; +#ifdef _WIN32 + DWORD win32_last_err = GetLastError(); +#endif + + rb_thread_local_aset(rb_thread_current(), rb_dl_id_DLErrno, INT2NUM(last_errno)); +#ifdef _WIN32 + rb_thread_local_aset(rb_thread_current(), rb_dl_id_DLW32Error, INT2NUM(win32_last_err)); +#endif + } + } #else /* defined(DLSTACK) */ switch(ftype){ @@ -835,4 +887,13 @@ Init_dlsym() rb_define_method(rb_cDLSymbol, "to_s", rb_dlsym_cproto, 0); rb_define_method(rb_cDLSymbol, "to_ptr", rb_dlsym_to_ptr, 0); rb_define_method(rb_cDLSymbol, "to_i", rb_dlsym_to_i, 0); + + rb_dl_id_DLErrno = rb_intern("DLErrno"); + rb_define_singleton_method(rb_mDL, "last_error", rb_dl_get_last_error, 0); + rb_define_singleton_method(rb_mDL, "last_error=", rb_dl_set_last_error, 1); +#ifdef _WIN32 + rb_dl_id_DLW32Error = rb_intern("DLW32Error"); + rb_define_singleton_method(rb_mDL, "win32_last_error", rb_dl_win32_get_last_error, 0); + rb_define_singleton_method(rb_mDL, "win32_last_error=", rb_dl_win32_set_last_error, 1); +#endif } -- cgit v1.2.3