diff --git a/python/types.c b/python/types.c --- a/python/types.c +++ b/python/types.c @@ -21,16 +21,66 @@ #if PY_MAJOR_VERSION >= 3 #include +#ifdef _WIN32 +#include +#else #include #include +#endif FILE * libxml_PyFileGet(PyObject *f) { - int fd, flags; + int fd; FILE *res; const char *mode; fd = PyObject_AsFileDescriptor(f); +#ifdef _WIN32 + PyObject *modeObj, *modeBytes; + + modeObj = PyObject_GetAttrString(f, "mode"); + if (!modeObj) + return(NULL); + + /* using f.mode to replace posix fcntl(), see + * https://gist.github.com/novocaine/09d5c00e67fd0aa13cfc */ + if (PyUnicode_Check(modeObj)) { + modeBytes = PyObject_CallMethod( + modeObj, "encode", "ascii", "namereplace"); + 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) { + _close(fd); + return(NULL); + } + return(res); +#else + int flags; /* * Get the flags on the fd to understand how it was opened */ @@ -76,6 +126,7 @@ libxml_PyFileGet(PyObject *f) { return(NULL); } return(res); +#endif } void libxml_PyFileRelease(FILE *f) {