diff options
author | Steve Dower <steve.dower@microsoft.com> | 2017-07-17 09:15:48 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-07-17 09:15:48 (GMT) |
commit | 68d663cf85d1ac5eaf83482eed39c0a6f8093601 (patch) | |
tree | fe26ff995655c31aca2d5c0f7bc4f8048cca5cc4 /Modules/_ssl.c | |
parent | 49f6449ef4b81537c19b82329caaf60596c516c2 (diff) | |
download | cpython-68d663cf85d1ac5eaf83482eed39c0a6f8093601.zip cpython-68d663cf85d1ac5eaf83482eed39c0a6f8093601.tar.gz cpython-68d663cf85d1ac5eaf83482eed39c0a6f8093601.tar.bz2 |
[bpo-30916] Pre-build OpenSSL and Tcl/Tk for Windows (#2688)
Updates ssl and tkinter projects to use pre-built externals
Diffstat (limited to 'Modules/_ssl.c')
-rw-r--r-- | Modules/_ssl.c | 38 |
1 files changed, 37 insertions, 1 deletions
diff --git a/Modules/_ssl.c b/Modules/_ssl.c index a79a747..458d2e7 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -21,11 +21,13 @@ #ifdef WITH_THREAD #include "pythread.h" +/* Redefined below for Windows debug builds after important #includes */ +#define _PySSL_FIX_ERRNO #define PySSL_BEGIN_ALLOW_THREADS_S(save) \ do { if (_ssl_locks_count>0) { (save) = PyEval_SaveThread(); } } while (0) #define PySSL_END_ALLOW_THREADS_S(save) \ - do { if (_ssl_locks_count>0) { PyEval_RestoreThread(save); } } while (0) + do { if (_ssl_locks_count>0) { PyEval_RestoreThread(save); } _PySSL_FIX_ERRNO; } while (0) #define PySSL_BEGIN_ALLOW_THREADS { \ PyThreadState *_save = NULL; \ PySSL_BEGIN_ALLOW_THREADS_S(_save); @@ -96,6 +98,40 @@ struct py_ssl_library_code { int code; }; +#if defined(MS_WINDOWS) && defined(Py_DEBUG) +/* Debug builds on Windows rely on getting errno directly from OpenSSL. + * However, because it uses a different CRT, we need to transfer the + * value of errno from OpenSSL into our debug CRT. + * + * Don't be fooled - this is horribly ugly code. The only reasonable + * alternative is to do both debug and release builds of OpenSSL, which + * requires much uglier code to transform their automatically generated + * makefile. This is the lesser of all the evils. + */ + +static void _PySSLFixErrno(void) { + HMODULE ucrtbase = GetModuleHandleW(L"ucrtbase.dll"); + if (!ucrtbase) { + /* If ucrtbase.dll is not loaded but the SSL DLLs are, we likely + * have a catastrophic failure, but this function is not the + * place to raise it. */ + return; + } + + typedef int *(__stdcall *errno_func)(void); + errno_func ssl_errno = (errno_func)GetProcAddress(ucrtbase, "_errno"); + if (ssl_errno) { + errno = *ssl_errno(); + *ssl_errno() = 0; + } else { + errno = ENOTRECOVERABLE; + } +} + +#undef _PySSL_FIX_ERRNO +#define _PySSL_FIX_ERRNO _PySSLFixErrno() +#endif + /* Include generated data (error codes) */ #include "_ssl_data.h" |