From fd4af23351b0c8a14a9e17906f4bb16dba3370e3 Mon Sep 17 00:00:00 2001 From: nospam Date: Sat, 27 Aug 2022 21:30:33 +0300 Subject: [PATCH] Support python modules on Windows for MinGW. --- acx_python.m4 | 5 ++++ configure.ac | 4 +++ libunbound/python/file_py3.i | 58 ++++++++++++++++++++++++++++++++++++ 3 files changed, 67 insertions(+) diff --git a/acx_python.m4 b/acx_python.m4 index 16c0c6fd9..096cddea3 100644 --- a/acx_python.m4 +++ b/acx_python.m4 @@ -70,8 +70,13 @@ AC_DEFUN([AC_PYTHON_DEVEL],[ # AC_MSG_CHECKING([for Python library path]) if test -z "$PYTHON_LDFLAGS"; then + if test $on_mingw = "yes"; then + PYTHON_LDFLAGS=`$PYTHON -c "from $sysconfig_module import *; \ + print('-L'+get_config_var('LIBDIR')+' -L'+get_config_var('LIBDEST')+' '+get_config_var('LIBPYTHON')+'.dll');"` + else PYTHON_LDFLAGS=`$PYTHON -c "from $sysconfig_module import *; \ print('-L'+get_config_var('LIBDIR')+' -L'+get_config_var('LIBDEST')+' '+get_config_var('BLDLIBRARY'));"` + fi fi AC_MSG_RESULT([$PYTHON_LDFLAGS]) AC_SUBST([PYTHON_LDFLAGS]) diff --git a/configure.ac b/configure.ac index bf8aa9d8c..08e59c564 100644 --- a/configure.ac +++ b/configure.ac @@ -569,6 +569,10 @@ else fi fi +if test "$on_mingw" = "yes"; then + LIBS="$LIBS -lntdll" +fi + # check windows threads (we use them, not pthreads, on windows). if test "$on_mingw" = "yes"; then # check windows threads diff --git a/libunbound/python/file_py3.i b/libunbound/python/file_py3.i index 5d8b5a271..9e9be428e 100644 --- a/libunbound/python/file_py3.i +++ b/libunbound/python/file_py3.i @@ -32,12 +32,62 @@ %{ #include #include +#ifdef __MINGW32__ +#define WIN32_LEAN_AND_MEAN +#include +#endif %} %types(FILE *); //#define SWIG_FILE3_DEBUG +%{ +#ifdef __MINGW32__ +typedef LONG NTSTATUS; +typedef struct _IO_STATUS_BLOCK { + union { + NTSTATUS Status; + PVOID Pointer; + }; + ULONG_PTR Information; + +} IO_STATUS_BLOCK, * PIO_STATUS_BLOCK; +typedef enum _FILE_INFORMATION_CLASS { + FileAccessInformation = 8, +} FILE_INFORMATION_CLASS, * PFILE_INFORMATION_CLASS; +typedef struct _FILE_ACCESS_INFORMATION { + ACCESS_MASK AccessFlags; +} FILE_ACCESS_INFORMATION, * PFILE_ACCESS_INFORMATION; +extern NTSTATUS __stdcall NtQueryInformationFile( + /*IN*/ HANDLE FileHandle, + /*OUT*/ PIO_STATUS_BLOCK IoStatusBlock, + /*OUT*/ PVOID FileInformation, + /*IN*/ ULONG Length, + /*IN*/ FILE_INFORMATION_CLASS FileInformationClass +); +int fcntl_getfl(int fd) +{ + intptr_t fh; + NTSTATUS ntrc; + IO_STATUS_BLOCK sb; + FILE_ACCESS_INFORMATION fi; + int is_r, is_w; + fh = _get_osfhandle(fh); + if (fh == -1) { return -1; } + ntrc = NtQueryInformationFile((HANDLE)fh, &sb, &fi, sizeof(fi), FileAccessInformation); + if (ntrc != 0) { return -1; } + is_r = (fi.AccessFlags & FILE_READ_DATA) == FILE_READ_DATA; + is_w = (fi.AccessFlags & FILE_WRITE_DATA) == FILE_WRITE_DATA; + if (is_r && is_w) { return _O_RDWR; } + if (is_w) { return _O_WRONLY; } + if (is_r) { return _O_RDONLY; } + return -1; +} +#endif +%} + + /* converts basic file descriptor flags onto a string */ %fragment("fdfl_to_str", "header") { const char * @@ -63,7 +113,11 @@ is_obj_file(PyObject *obj) { PyObject_HasAttrString(obj, "fileno") && /* has fileno method */ (PyObject_CallMethod(obj, "flush", NULL) != NULL) && /* flush() succeeded */ ((fd = PyObject_AsFileDescriptor(obj)) != -1) && /* got file descriptor */ +%#ifdef __MINGW32__ + ((fdfl = fcntl_getfl(fd)) != -1) +%#else ((fdfl = fcntl(fd, F_GETFL)) != -1) /* got descriptor flags */ +%#endif ) { return 1; } @@ -80,7 +134,11 @@ obj_to_file(PyObject *obj) { FILE *fp; if (is_obj_file(obj)) { fd = PyObject_AsFileDescriptor(obj); +%#ifdef __MINGW32__ + fdfl = fcntl_getfl(fd); +%#else fdfl = fcntl(fd, F_GETFL); +%#endif fp = fdopen(dup(fd), fdfl_to_str(fdfl)); /* the FILE* must be flushed and closed after being used */ #ifdef SWIG_FILE3_DEBUG