diff --git a/racket/src/foreign/foreign.c b/racket/src/foreign/foreign.c index 28657f947a..01147ed9ff 100644 --- a/racket/src/foreign/foreign.c +++ b/racket/src/foreign/foreign.c @@ -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; } diff --git a/racket/src/foreign/foreign.rktc b/racket/src/foreign/foreign.rktc index d54571a928..c9d81905c4 100755 --- a/racket/src/foreign/foreign.rktc +++ b/racket/src/foreign/foreign.rktc @@ -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; }