diff options
Diffstat (limited to 'giscanner/giscannermodule.c')
-rw-r--r-- | giscanner/giscannermodule.c | 94 |
1 files changed, 93 insertions, 1 deletions
diff --git a/giscanner/giscannermodule.c b/giscanner/giscannermodule.c index a024f1a0..c37357bd 100644 --- a/giscanner/giscannermodule.c +++ b/giscanner/giscannermodule.c @@ -24,7 +24,15 @@ #endif #include <Python.h> #include "sourcescanner.h" -#include <stdio.h> + +#ifdef _WIN32 +#include <fcntl.h> +#include <io.h> +#define WIN32_LEAN_AND_MEAN +#define STRICT +#include <windows.h> +#endif + #include <glib-object.h> #ifndef Py_TYPE @@ -439,6 +447,90 @@ pygi_source_scanner_parse_file (PyGISourceScanner *self, if (!PyArg_ParseTuple (args, "i:SourceScanner.parse_file", &fd)) return NULL; +#ifdef _WIN32 + /* The file descriptor passed to us is from the C library Python + * uses. That is msvcr71.dll for Python 2.5 and msvcr90.dll for + * Python 2.6, 2.7, 3.2 etc; and msvcr100.dll for Python 3.3 and 3.4. + * Python 3.5 and later is built with Visual Studio 2015, which uses + * the universal CRT, so we need to deal with urtbase.dll here instead. + * This code, at least if compiled with mingw, uses + * msvcrt.dll, so we cannot use the file descriptor directly. So + * perform appropriate magic. + */ + + /* If we are using the following combinations, + * we can use the file descriptors directly + * (Not if a build using WDK is used): + * Python 2.6.x/2.7.x with Visual C++ 2008 + * Python 3.1.x/3.2.x with Visual C++ 2008 + * Python 3.3.x/3.4.x with Visual C++ 2010 + */ + + /* XXX: Somehow we cannot use the FD directly on Python 3.5+ even when + * using Visual Studio 2015, so we currently need to use _get_osfhandle() when + * in all cases on Python 3.5+ + */ + +#if (defined(_MSC_VER) && !defined(USE_WIN_DDK)) +#if (PY_MAJOR_VERSION==2 && PY_MINOR_VERSION>=6 && (_MSC_VER >= 1500 && _MSC_VER < 1600)) +#define MSVC_USE_FD_DIRECTLY 1 +#elif (PY_MAJOR_VERSION==3 && PY_MINOR_VERSION<=2 && (_MSC_VER >= 1500 && _MSC_VER < 1600)) +#define MSVC_USE_FD_DIRECTLY 1 +#elif (PY_MAJOR_VERSION==3 && PY_MINOR_VERSION<=4 && (_MSC_VER >= 1600 && _MSC_VER < 1700)) +#define MSVC_USE_FD_DIRECTLY 1 +#endif +#endif + +#if !defined(MSVC_USE_FD_DIRECTLY) && !defined(__MINGW64_VERSION_MAJOR) + { +#if defined(PY_MAJOR_VERSION) && PY_MAJOR_VERSION==2 && PY_MINOR_VERSION==5 +#define PYTHON_MSVCRXX_DLL "msvcr71.dll" +#elif defined(PY_MAJOR_VERSION) && PY_MAJOR_VERSION==2 && PY_MINOR_VERSION==7 +#define PYTHON_MSVCRXX_DLL "msvcr90.dll" +#elif defined(PY_MAJOR_VERSION) && PY_MAJOR_VERSION==3 && PY_MINOR_VERSION<=2 +#define PYTHON_MSVCRXX_DLL "msvcr90.dll" +#elif defined(PY_MAJOR_VERSION) && PY_MAJOR_VERSION==3 && PY_MINOR_VERSION<=4 +#define PYTHON_MSVCRXX_DLL "msvcr100.dll" +#elif defined(PY_MAJOR_VERSION) && PY_MAJOR_VERSION==3 && PY_MINOR_VERSION>=5 +#define PYTHON_MSVCRXX_DLL "ucrtbase.dll" +#else +#error This Python version not handled +#endif + HMODULE msvcrxx; + intptr_t (*p__get_osfhandle) (int); + HANDLE handle; + + msvcrxx = GetModuleHandle (PYTHON_MSVCRXX_DLL); + if (!msvcrxx) + { + g_print ("No " PYTHON_MSVCRXX_DLL " loaded.\n"); + return NULL; + } + + p__get_osfhandle = (intptr_t (*) (int)) GetProcAddress (msvcrxx, "_get_osfhandle"); + if (!p__get_osfhandle) + { + g_print ("No _get_osfhandle found in " PYTHON_MSVCRXX_DLL ".\n"); + return NULL; + } + + handle = (HANDLE) p__get_osfhandle (fd); + if (!p__get_osfhandle) + { + g_print ("Could not get OS handle from " PYTHON_MSVCRXX_DLL " fd.\n"); + return NULL; + } + + fd = _open_osfhandle ((intptr_t) handle, _O_RDONLY); + if (fd == -1) + { + g_print ("Could not open C fd from OS handle.\n"); + return NULL; + } + } +#endif +#endif + fp = fdopen (fd, "r"); if (!fp) { |