Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add FFI::LastError.win_error #633

Merged
merged 3 commits into from Jan 6, 2019
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
49 changes: 47 additions & 2 deletions ext/ffi_c/LastError.c
Expand Up @@ -49,8 +49,17 @@
# define USE_PTHREAD_LOCAL
#endif

#if defined(_WIN32) || defined(__CYGWIN__)
typedef uint32_t DWORD;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you declare these functions? This shouldn't be necessary and breaks the MINGW build: https://ci.appveyor.com/project/larskanis/ffi-aofqa/build/1.0.30

Copy link
Contributor Author

@graywolf graywolf May 30, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm stupid, this should obviously be only on cygwin, fixed

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)
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: 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)
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_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)
{
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, "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
Expand Down