From e5132c74e4072ea8dab16a52ef78e5d5b0d84df5 Mon Sep 17 00:00:00 2001 From: Wolf Date: Tue, 29 May 2018 22:10:13 +0200 Subject: [PATCH 1/3] Add FFI::LastError.win_error Under cygwin both errno and GetLastError are needed. This adds second getter named #win_error: Linux FFI::LastError.error == errno FFI::LastError.win_error == NoMethodError Windows FFI::LastError.error == GetLastError FFI::LastError.win_error == GetLastError Cygwin FFI::LastError.error == errno FFI::LastError.win_error == GetLastError --- ext/ffi_c/LastError.c | 49 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 47 insertions(+), 2 deletions(-) diff --git a/ext/ffi_c/LastError.c b/ext/ffi_c/LastError.c index 795a42e55..aa7e364c8 100644 --- a/ext/ffi_c/LastError.c +++ b/ext/ffi_c/LastError.c @@ -49,8 +49,17 @@ # define USE_PTHREAD_LOCAL #endif +#if defined(_WIN32) || defined(__CYGWIN__) +typedef uint32_t DWORD; +DWORD __stdcall GetLastError(void); +void __stdcall SetLastError(DWORD); +#endif + typedef struct ThreadData { int td_errno; +#if defined(_WIN32) || defined(__CYGWIN__) + DWORD td_win_errno; +#endif } ThreadData; #if defined(USE_PTHREAD_LOCAL) @@ -126,6 +135,19 @@ get_last_error(VALUE self) return INT2NUM(thread_data_get()->td_errno); } +#if defined(_WIN32) || defined(__CYGWIN__) +/* + * call-seq: win_error + * @return [Numeric] + * Get +GetLastError()+ value. Only Windows or Cygwin. + */ +static VALUE +get_last_win_error(VALUE self) +{ + return INT2NUM(thread_data_get()->td_win_errno); +} +#endif + /* * call-seq: error(error) @@ -146,22 +168,40 @@ set_last_error(VALUE self, VALUE error) return Qnil; } +#if defined(_WIN32) || defined(__CYGWIN__) +/* + * call-seq: error(error) + * @param [Numeric] error + * @return [nil] + * Set +GetLastError()+ value. Only on Windows and Cygwin. + */ +static VALUE +set_last_win_error(VALUE self, VALUE error) +{ + SetLastError(NUM2INT(error)); + return Qnil; +} +#endif + void rbffi_save_errno(void) { int error = 0; - #ifdef _WIN32 error = GetLastError(); #else error = errno; #endif +#if defined(_WIN32) || defined(__CYGWIN__) + DWORD win_error = GetLastError(); + thread_data_get()->td_win_errno = win_error; +#endif + thread_data_get()->td_errno = error; } - void rbffi_LastError_Init(VALUE moduleFFI) { @@ -175,6 +215,11 @@ rbffi_LastError_Init(VALUE moduleFFI) rb_define_module_function(moduleError, "error", get_last_error, 0); rb_define_module_function(moduleError, "error=", set_last_error, 1); +#if defined(_WIN32) || defined(__CYGWIN__) + rb_define_module_function(moduleError, "win_error", get_last_win_error, 0); + rb_define_module_function(moduleError, "win_error=", set_last_win_error, 1); +#endif + #if defined(USE_PTHREAD_LOCAL) pthread_key_create(&threadDataKey, thread_data_free); #else From 4ba55c57c14e36e4b163e337ebb92e5e7a5c4ab4 Mon Sep 17 00:00:00 2001 From: Wolf Date: Wed, 30 May 2018 11:17:28 +0200 Subject: [PATCH 2/3] Rename to winapi_error --- ext/ffi_c/LastError.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/ext/ffi_c/LastError.c b/ext/ffi_c/LastError.c index aa7e364c8..8d7c74502 100644 --- a/ext/ffi_c/LastError.c +++ b/ext/ffi_c/LastError.c @@ -58,7 +58,7 @@ void __stdcall SetLastError(DWORD); typedef struct ThreadData { int td_errno; #if defined(_WIN32) || defined(__CYGWIN__) - DWORD td_win_errno; + DWORD td_winapi_errno; #endif } ThreadData; @@ -137,14 +137,14 @@ get_last_error(VALUE self) #if defined(_WIN32) || defined(__CYGWIN__) /* - * call-seq: win_error + * call-seq: winapi_error * @return [Numeric] * Get +GetLastError()+ value. Only Windows or Cygwin. */ static VALUE -get_last_win_error(VALUE self) +get_last_winapi_error(VALUE self) { - return INT2NUM(thread_data_get()->td_win_errno); + return INT2NUM(thread_data_get()->td_winapi_errno); } #endif @@ -176,7 +176,7 @@ set_last_error(VALUE self, VALUE error) * Set +GetLastError()+ value. Only on Windows and Cygwin. */ static VALUE -set_last_win_error(VALUE self, VALUE error) +set_last_winapi_error(VALUE self, VALUE error) { SetLastError(NUM2INT(error)); return Qnil; @@ -195,8 +195,8 @@ rbffi_save_errno(void) #endif #if defined(_WIN32) || defined(__CYGWIN__) - DWORD win_error = GetLastError(); - thread_data_get()->td_win_errno = win_error; + DWORD winapi_error = GetLastError(); + thread_data_get()->td_winapi_errno = winapi_error; #endif thread_data_get()->td_errno = error; @@ -216,8 +216,8 @@ rbffi_LastError_Init(VALUE moduleFFI) rb_define_module_function(moduleError, "error=", set_last_error, 1); #if defined(_WIN32) || defined(__CYGWIN__) - rb_define_module_function(moduleError, "win_error", get_last_win_error, 0); - rb_define_module_function(moduleError, "win_error=", set_last_win_error, 1); + rb_define_module_function(moduleError, "winapi_error", get_last_winapi_error, 0); + rb_define_module_function(moduleError, "winapi_error=", set_last_winapi_error, 1); #endif #if defined(USE_PTHREAD_LOCAL) From 447bdca729d0643b6586360e54bca143d5e78386 Mon Sep 17 00:00:00 2001 From: Wolf Date: Wed, 30 May 2018 11:17:59 +0200 Subject: [PATCH 3/3] Declare DWORD, {Get,Set}LastError only on cygwin --- ext/ffi_c/LastError.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/ffi_c/LastError.c b/ext/ffi_c/LastError.c index 8d7c74502..8a460f3b4 100644 --- a/ext/ffi_c/LastError.c +++ b/ext/ffi_c/LastError.c @@ -49,7 +49,7 @@ # define USE_PTHREAD_LOCAL #endif -#if defined(_WIN32) || defined(__CYGWIN__) +#if defined(__CYGWIN__) typedef uint32_t DWORD; DWORD __stdcall GetLastError(void); void __stdcall SetLastError(DWORD);