[libxslt] python: Support Python 3 on Windows
- From: Nick Wellnhofer <nwellnhof src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libxslt] python: Support Python 3 on Windows
- Date: Tue, 6 Sep 2022 20:58:31 +0000 (UTC)
commit 5443ca169cb7517d394ed8c34442c7d94bef6837
Author: Nick Wellnhofer <wellnhofer aevum de>
Date: Tue Sep 6 13:36:42 2022 +0200
python: Support Python 3 on Windows
Copy updated implementation of PyFileGET from libxml2.
python/types.c | 190 +++++++++++++++++++++++++++++++++++++++++++++++++--------
1 file changed, 165 insertions(+), 25 deletions(-)
---
diff --git a/python/types.c b/python/types.c
index 1617cb96..651f17dd 100644
--- a/python/types.c
+++ b/python/types.c
@@ -25,42 +25,182 @@ xmlParserInputPtr xmlNoNetExternalEntityLoader(const char *URL,
#if PY_MAJOR_VERSION >= 3
#include <stdio.h>
+#include <stdint.h>
+
+#ifdef _WIN32
+
+#include <windows.h>
+#include <crtdbg.h>
+
+/* Taken from info on MSDN site, as we may not have the Windows WDK/DDK headers */
+typedef struct _IO_STATUS_BLOCK {
+ union {
+ NTSTATUS Status;
+ PVOID Pointer;
+ } DUMMYUNIONNAME;
+ ULONG_PTR Information;
+} IO_STATUS_BLOCK;
+
+typedef struct _FILE_ACCESS_INFORMATION {
+ ACCESS_MASK AccessFlags;
+} FILE_ACCESS_INFORMATION;
+
+typedef NTSTATUS (*t_NtQueryInformationFile) (HANDLE FileHandle,
+ IO_STATUS_BLOCK *IoStatusBlock,
+ PVOID FileInformation,
+ ULONG Length,
+ int FileInformationClass); /* this is an Enum */
+
+#if (defined (_MSC_VER) && _MSC_VER >= 1400)
+/*
+ * This is the (empty) invalid parameter handler
+ * that is used for Visual C++ 2005 (and later) builds
+ * so that we can use this instead of the system automatically
+ * aborting the process.
+ *
+ * This is necessary as we use _get_oshandle() to check the validity
+ * of the file descriptors as we close them, so when an invalid file
+ * descriptor is passed into that function as we check on it, we get
+ * -1 as the result, instead of the gspawn helper program aborting.
+ *
+ * Please see http://msdn.microsoft.com/zh-tw/library/ks2530z6%28v=vs.80%29.aspx
+ * for an explanation on this.
+ */
+void
+myInvalidParameterHandler(const wchar_t *expression,
+ const wchar_t *function,
+ const wchar_t *file,
+ unsigned int line,
+ uintptr_t pReserved)
+{
+}
+#endif
+#else
#include <unistd.h>
#include <fcntl.h>
+#endif
FILE *
libxml_PyFileGet(PyObject *f) {
- int fd, flags;
FILE *res;
const char *mode;
+ int fd = PyObject_AsFileDescriptor(f);
+
+#ifdef _WIN32
+ intptr_t w_fh = -1;
+ HMODULE hntdll = NULL;
+ IO_STATUS_BLOCK status_block;
+ FILE_ACCESS_INFORMATION ai;
+ t_NtQueryInformationFile NtQueryInformationFile;
+ BOOL is_read = FALSE;
+ BOOL is_write = FALSE;
+ BOOL is_append = FALSE;
+
+#if (defined (_MSC_VER) && _MSC_VER >= 1400)
+ /* set up our empty invalid parameter handler */
+ _invalid_parameter_handler oldHandler, newHandler;
+ newHandler = myInvalidParameterHandler;
+ oldHandler = _set_invalid_parameter_handler(newHandler);
+
+ /* Disable the message box for assertions. */
+ _CrtSetReportMode(_CRT_ASSERT, 0);
+#endif
+
+ w_fh = _get_osfhandle(fd);
+
+ if (w_fh == -1)
+ return(NULL);
+
+ hntdll = GetModuleHandleW(L"ntdll.dll");
+
+ if (hntdll == NULL)
+ return(NULL);
+XML_IGNORE_FPTR_CAST_WARNINGS
+ NtQueryInformationFile = (t_NtQueryInformationFile)GetProcAddress(hntdll, "NtQueryInformationFile");
+XML_POP_WARNINGS
+
+ if (NtQueryInformationFile != NULL &&
+ (NtQueryInformationFile((HANDLE)w_fh,
+ &status_block,
+ &ai,
+ sizeof(FILE_ACCESS_INFORMATION),
+ 8) == 0)) /* 8 means "FileAccessInformation" */
+ {
+ if (ai.AccessFlags & FILE_READ_DATA)
+ is_read = TRUE;
+ if (ai.AccessFlags & FILE_WRITE_DATA)
+ is_write = TRUE;
+ if (ai.AccessFlags & FILE_APPEND_DATA)
+ is_append = TRUE;
+
+ if (is_write) {
+ if (is_read) {
+ if (is_append)
+ mode = "a+";
+ else
+ mode = "rw";
+ } else {
+ if (is_append)
+ mode = "a";
+ else
+ mode = "w";
+ }
+ } else {
+ if (is_append)
+ mode = "r+";
+ else
+ mode = "r";
+ }
+ }
+
+ FreeLibrary(hntdll);
+
+ if (!is_write && !is_read) /* also happens if we did not load or run NtQueryInformationFile()
successfully */
+ return(NULL);
+#else
+ int flags;
- fd = PyObject_AsFileDescriptor(f);
/*
- * Get the flags on the fd to understand how it was opened
+ * macOS returns O_RDWR for standard streams, but fails to write to
+ * stdout or stderr when opened with fdopen(dup_fd, "rw").
*/
- flags = fcntl(fd, F_GETFL, 0);
- switch (flags & O_ACCMODE) {
- case O_RDWR:
- if (flags & O_APPEND)
- mode = "a+";
- else
- mode = "rw";
- break;
- case O_RDONLY:
- if (flags & O_APPEND)
- mode = "r+";
- else
- mode = "r";
- break;
- case O_WRONLY:
- if (flags & O_APPEND)
- mode = "a";
- else
- mode = "w";
- break;
- default:
- return(NULL);
+ switch (fd) {
+ case STDIN_FILENO:
+ mode = "r";
+ break;
+ case STDOUT_FILENO:
+ case STDERR_FILENO:
+ mode = "w";
+ break;
+ default:
+ /*
+ * Get the flags on the fd to understand how it was opened
+ */
+ flags = fcntl(fd, F_GETFL, 0);
+ switch (flags & O_ACCMODE) {
+ case O_RDWR:
+ if (flags & O_APPEND)
+ mode = "a+";
+ else
+ mode = "rw";
+ break;
+ case O_RDONLY:
+ if (flags & O_APPEND)
+ mode = "r+";
+ else
+ mode = "r";
+ break;
+ case O_WRONLY:
+ if (flags & O_APPEND)
+ mode = "a";
+ else
+ mode = "w";
+ break;
+ default:
+ return(NULL);
+ }
}
+#endif
/*
* the FILE struct gets a new fd, so that it can be closed
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]