Last active
August 29, 2015 14:14
-
-
Save novocaine/09d5c00e67fd0aa13cfc to your computer and use it in GitHub Desktop.
fix libxml2 2.9.2 python 3 on windows
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff -ur libxml2-2.9.2.old/python/setup.py libxml2-2.9.2/python/setup.py | |
--- libxml2-2.9.2.old/python/setup.py 2014-10-16 09:35:22.000000000 +0100 | |
+++ libxml2-2.9.2/python/setup.py 2015-01-22 12:23:18.804795900 +0000 | |
@@ -123,7 +123,7 @@ | |
with_xslt=0 | |
if missing("libxslt-py.c") or missing("libxslt.py"): | |
- if missing("xsltgenerator.py") or missing("libxslt-api.xml"): | |
+ if missing("xsltgenerator.py") or missing("libxslt-python-api.xml"): | |
print("libxslt stub generator not found, libxslt not built") | |
else: | |
try: | |
@@ -192,7 +192,6 @@ | |
includes.append(xslt_includes) | |
modules.append('libxslt') | |
- | |
extens=[Extension('libxml2mod', c_files, include_dirs=includes, | |
library_dirs=libdirs, | |
libraries=libs, define_macros=macros)] | |
diff -ur libxml2-2.9.2.old/python/setup.py.in libxml2-2.9.2/python/setup.py.in | |
--- libxml2-2.9.2.old/python/setup.py.in 2014-10-16 05:46:36.000000000 +0100 | |
+++ libxml2-2.9.2/python/setup.py.in 2015-01-22 12:24:13.423100400 +0000 | |
@@ -123,7 +123,7 @@ | |
with_xslt=0 | |
if missing("libxslt-py.c") or missing("libxslt.py"): | |
- if missing("xsltgenerator.py") or missing("libxslt-api.xml"): | |
+ if missing("xsltgenerator.py") or missing("libxslt-python-api.xml"): | |
print("libxslt stub generator not found, libxslt not built") | |
else: | |
try: | |
diff -ur libxml2-2.9.2.old/python/types.c libxml2-2.9.2/python/types.c | |
--- libxml2-2.9.2.old/python/types.c 2014-10-03 11:00:54.000000000 +0100 | |
+++ libxml2-2.9.2/python/types.c 2015-01-22 12:04:53.157630900 +0000 | |
@@ -21,18 +21,115 @@ | |
#if PY_MAJOR_VERSION >= 3 | |
#include <stdio.h> | |
+ | |
+#ifndef _WIN32 | |
#include <unistd.h> | |
#include <fcntl.h> | |
+#else | |
+#include <io.h> | |
+#endif | |
+ | |
+/* On unix, _PyVerify_fd is a no-op macro; on windows it is | |
+ * defined in .c and not exported, so we replicate it here | |
+ * (from (python 3 source)/Modules/posixmodule.c) | |
+ * | |
+ * Performing this check is vital to prevent run-time | |
+ * assertions due to invalid fds. */ | |
+ | |
+#if defined _WIN32 && _MSC_VER && _MSC_VER >= 1400 | |
+#include <malloc.h> | |
+/* Microsoft CRT in VS2005 and higher will verify that a filehandle is | |
+ * valid and raise an assertion if it isn't. | |
+ * Normally, an invalid fd is likely to be a C program error and therefore | |
+ * an assertion can be useful, but it does contradict the POSIX standard | |
+ * which for write(2) states: | |
+ * "Otherwise, -1 shall be returned and errno set to indicate the error." | |
+ * "[EBADF] The fildes argument is not a valid file descriptor open for | |
+ * writing." | |
+ * Furthermore, python allows the user to enter any old integer | |
+ * as a fd and should merely raise a python exception on error. | |
+ * The Microsoft CRT doesn't provide an official way to check for the | |
+ * validity of a file descriptor, but we can emulate its internal behaviour | |
+ * by using the exported __pinfo data member and knowledge of the | |
+ * internal structures involved. | |
+ * The structures below must be updated for each version of visual studio | |
+ * according to the file internal.h in the CRT source, until MS comes | |
+ * up with a less hacky way to do this. | |
+ * (all of this is to avoid globally modifying the CRT behaviour using | |
+ * _set_invalid_parameter_handler() and _CrtSetReportMode()) | |
+ */ | |
+/* The actual size of the structure is determined at runtime. | |
+ * Only the first items must be present. | |
+ */ | |
+typedef struct { | |
+ intptr_t osfhnd; | |
+ char osfile; | |
+} my_ioinfo; | |
+ | |
+extern __declspec(dllimport) char * __pioinfo[]; | |
+#define IOINFO_L2E 5 | |
+#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E) | |
+#define IOINFO_ARRAYS 64 | |
+#define _NHANDLE_ (IOINFO_ARRAYS * IOINFO_ARRAY_ELTS) | |
+#define FOPEN 0x01 | |
+#define _NO_CONSOLE_FILENO (intptr_t)-2 | |
+ | |
+/* This function emulates what the windows CRT does to validate file handles */ | |
+int | |
+_PyVerify_fd(int fd) | |
+{ | |
+ const int i1 = fd >> IOINFO_L2E; | |
+ const int i2 = fd & ((1 << IOINFO_L2E) - 1); | |
+ | |
+ static size_t sizeof_ioinfo = 0; | |
+ | |
+ /* Determine the actual size of the ioinfo structure, | |
+ * as used by the CRT loaded in memory | |
+ */ | |
+ if (sizeof_ioinfo == 0 && __pioinfo[0] != NULL) { | |
+ sizeof_ioinfo = _msize(__pioinfo[0]) / IOINFO_ARRAY_ELTS; | |
+ } | |
+ if (sizeof_ioinfo == 0) { | |
+ /* This should not happen... */ | |
+ goto fail; | |
+ } | |
+ | |
+ /* See that it isn't a special CLEAR fileno */ | |
+ if (fd != _NO_CONSOLE_FILENO) { | |
+ /* Microsoft CRT would check that 0<=fd<_nhandle but we can't do that. Instead | |
+ * we check pointer validity and other info | |
+ */ | |
+ if (0 <= i1 && i1 < IOINFO_ARRAYS && __pioinfo[i1] != NULL) { | |
+ /* finally, check that the file is open */ | |
+ my_ioinfo* info = (my_ioinfo*)(__pioinfo[i1] + i2 * sizeof_ioinfo); | |
+ if (info->osfile & FOPEN) { | |
+ return 1; | |
+ } | |
+ } | |
+ } | |
+ fail: | |
+ errno = EBADF; | |
+ return 0; | |
+} | |
+ | |
+#endif | |
FILE * | |
libxml_PyFileGet(PyObject *f) { | |
- int fd, flags; | |
+ int fd; | |
FILE *res; | |
const char *mode; | |
+#ifdef _WIN32 | |
+ PyObject *modeObj, *modeBytes; | |
+#else | |
+ int flags; | |
+#endif | |
fd = PyObject_AsFileDescriptor(f); | |
if (!_PyVerify_fd(fd)) | |
return(NULL); | |
+ | |
+#ifndef _WIN32 | |
/* | |
* Get the flags on the fd to understand how it was opened | |
*/ | |
@@ -78,6 +175,67 @@ | |
return(NULL); | |
} | |
return(res); | |
+#else | |
+ /* | |
+ * The mode sniffing above isn't possible on windows - | |
+ * the CRT simply doesn't expose an interface for | |
+ * retreiving the mode of the fd (even though it supports | |
+ * the same POSIX set at creation). | |
+ * | |
+ * So instead, we look for a .mode attribute on f. | |
+ * | |
+ * Python 3's open() always sets a .mode attribute | |
+ * before returning a value (even when a custom opener | |
+ * is provided), so this covers the majority of cases. | |
+ * | |
+ * This won't work for callers passing other file-like | |
+ * objects that don't implement .mode; they will just | |
+ * have to implement it somehow (hopefully they are | |
+ * just wrapping something that does know the mode). | |
+ */ | |
+ | |
+ modeObj = PyObject_GetAttrString(f, "mode"); | |
+ if (!modeObj) { | |
+ return(NULL); | |
+ } | |
+ | |
+ if (PyUnicode_Check(modeObj)) { | |
+ modeBytes = PyObject_CallMethod( | |
+ modeObj, "encode", "s", "ascii"); | |
+ if (!modeBytes) { | |
+ Py_DECREF(modeObj); | |
+ return(NULL); | |
+ } | |
+ mode = PyBytes_AsString(modeBytes); | |
+ if (!mode) { | |
+ Py_DECREF(modeObj); | |
+ return(NULL); | |
+ } | |
+ Py_DECREF(modeBytes); | |
+ } else if (PyBytes_Check(modeObj)) { | |
+ mode = PyBytes_AsString(modeObj); | |
+ if (!mode) { | |
+ Py_DECREF(modeObj); | |
+ return(NULL); | |
+ } | |
+ } else { | |
+ Py_DECREF(modeObj); | |
+ return(NULL); | |
+ } | |
+ | |
+ Py_DECREF(modeObj); | |
+ | |
+ fd = _dup(fd); | |
+ if (fd == -1) { | |
+ return(NULL); | |
+ } | |
+ res = _fdopen(fd, mode); | |
+ if (res == NULL) { | |
+ _close(fd); | |
+ return(NULL); | |
+ } | |
+ return(res); | |
+#endif | |
} | |
void libxml_PyFileRelease(FILE *f) { | |
Only in libxml2-2.9.2/win32: config.msvc | |
diff -ur libxml2-2.9.2.old/win32/configure.js libxml2-2.9.2/win32/configure.js | |
--- libxml2-2.9.2.old/win32/configure.js 2014-10-03 11:00:56.000000000 +0100 | |
+++ libxml2-2.9.2/win32/configure.js 2015-01-21 12:32:09.664068100 +0000 | |
@@ -14,7 +14,7 @@ | |
var baseName = "libxml2"; | |
/* Configure file which contains the version and the output file where | |
we can store our build configuration. */ | |
-var configFile = srcDirXml + "\\configure.in"; | |
+var configFile = srcDirXml + "\\configure.ac"; | |
var versionFile = ".\\config.msvc"; | |
/* Input and output files regarding the libxml features. */ | |
var optsFileIn = srcDirXml + "\\include\\libxml\\xmlversion.h.in"; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment