Windows: always get errno from "MSVCRT.dll"

This commit is contained in:
Matthew Flatt 2016-02-25 10:02:17 -06:00
parent 15f47ef62e
commit f0500c64d3
2 changed files with 54 additions and 2 deletions

View File

@ -3380,7 +3380,7 @@ static void release_ffi_lock(void *lock)
#define MAX_QUICK_ARGS 16
typedef void(*VoidFun)();
typedef void(*VoidFun)(void);
#ifdef MZ_USE_PLACES
@ -4244,6 +4244,11 @@ static Scheme_Object *foreign_ffi_callback(int argc, Scheme_Object *argv[])
/*****************************************************************************/
#ifdef WINDOWS_DYNAMIC_LOAD
typedef int *(*get_errno_ptr_t)(void);
static get_errno_ptr_t get_errno_ptr;
#endif /* WINDOWS_DYNAMIC_LOAD */
static void save_errno_values(int kind)
{
Scheme_Thread *p = scheme_current_thread;
@ -4257,6 +4262,27 @@ static void save_errno_values(int kind)
return;
}
# ifdef WINDOWS_DYNAMIC_LOAD
/* Depending on how Racket is compiled and linked, `errno` might
not corresponds to the one from "MSVCRT.dll", which is likely
to be the one that foreign code uses. Go get that one via
_errno(), which returns a pointer to the current thread's
`errno`. */
if (!get_errno_ptr) {
HMODULE hm;
hm = LoadLibrary("msvcrt.dll");
if (hm) {
get_errno_ptr = (get_errno_ptr_t)GetProcAddress(hm, "_errno");
}
}
if (get_errno_ptr) {
GC_CAN_IGNORE int *errno_ptr;
errno_ptr = get_errno_ptr();
errno = *errno_ptr;
}
# endif /* WINDOWS_DYNAMIC_LOAD */
p->saved_errno = errno;
}

View File

@ -2545,7 +2545,7 @@ static void release_ffi_lock(void *lock)
#define MAX_QUICK_ARGS 16
typedef void(*VoidFun)();
typedef void(*VoidFun)(void);
#ifdef MZ_USE_PLACES
@ -3399,6 +3399,11 @@ static void free_cl_cif_queue_args(void *ignored, void *p)
/*****************************************************************************/
@@IFDEF{WINDOWS_DYNAMIC_LOAD}{
typedef int *(*get_errno_ptr_t)(void);
static get_errno_ptr_t get_errno_ptr;
}
static void save_errno_values(int kind)
{
Scheme_Thread *p = scheme_current_thread;
@ -3412,6 +3417,27 @@ static void save_errno_values(int kind)
return;
}
@@IFDEF{WINDOWS_DYNAMIC_LOAD}{
/* Depending on how Racket is compiled and linked, `errno` might
not corresponds to the one from "MSVCRT.dll", which is likely
to be the one that foreign code uses. Go get that one via
_errno(), which returns a pointer to the current thread's
`errno`. */
if (!get_errno_ptr) {
HMODULE hm;
hm = LoadLibrary("msvcrt.dll");
if (hm) {
get_errno_ptr = (get_errno_ptr_t)GetProcAddress(hm, "_errno");
}
}
if (get_errno_ptr) {
GC_CAN_IGNORE int *errno_ptr;
errno_ptr = get_errno_ptr();
errno = *errno_ptr;
}
}
p->saved_errno = errno;
}