Skip to content

Commit

Permalink
Merge pull request #633 from graywolf/add_win_error
Browse files Browse the repository at this point in the history
Add FFI::LastError.win_error
  • Loading branch information
larskanis committed Jan 6, 2019
2 parents fa65b25 + 447bdca commit d7d642d
Showing 1 changed file with 47 additions and 2 deletions.
49 changes: 47 additions & 2 deletions ext/ffi_c/LastError.c
Expand Up @@ -49,8 +49,17 @@
# define USE_PTHREAD_LOCAL
#endif

#if 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_winapi_errno;
#endif
} ThreadData;

#if defined(USE_PTHREAD_LOCAL)
Expand Down Expand Up @@ -126,6 +135,19 @@ get_last_error(VALUE self)
return INT2NUM(thread_data_get()->td_errno);
}

#if defined(_WIN32) || defined(__CYGWIN__)
/*
* call-seq: winapi_error
* @return [Numeric]
* Get +GetLastError()+ value. Only Windows or Cygwin.
*/
static VALUE
get_last_winapi_error(VALUE self)
{
return INT2NUM(thread_data_get()->td_winapi_errno);
}
#endif


/*
* call-seq: error(error)
Expand All @@ -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_winapi_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 winapi_error = GetLastError();
thread_data_get()->td_winapi_errno = winapi_error;
#endif

thread_data_get()->td_errno = error;
}


void
rbffi_LastError_Init(VALUE moduleFFI)
{
Expand All @@ -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, "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)
pthread_key_create(&threadDataKey, thread_data_free);
#else
Expand Down

0 comments on commit d7d642d

Please sign in to comment.