diff --git a/Include/Python.h b/Include/Python.h index 6fbc49c..0168345 100644 --- a/Include/Python.h +++ b/Include/Python.h @@ -131,6 +131,11 @@ PyAPI_FUNC(PyObject*) _Py_Mangle(PyObject *p, PyObject *name); /* _Py_char2wchar lives in main.c */ PyAPI_FUNC(wchar_t *) _Py_char2wchar(char *); + +#ifdef HAVE_STAT +/* _Py_stat lives in import.c */ +int _Py_stat(PyObject *path, struct stat *statbuf); +#endif #ifdef __cplusplus } #endif diff --git a/Python/import.c b/Python/import.c index 194e360..dcb4f3c 100644 --- a/Python/import.c +++ b/Python/import.c @@ -1962,6 +1962,42 @@ case_ok(char *buf, Py_ssize_t len, Py_ssize_t namelen, char *name) #ifdef HAVE_STAT + +/* Call _wstat() on Windows, or stat() otherwise. Only fill st_mode + attribute on Windows. Return 0 on success, -1 on error. Clear unicode error + on path encoding failure. */ + +int +_Py_stat(PyObject *path, struct stat *statbuf) +{ + int err; +#ifdef MS_WINDOWS + wchar_t wpath[MAXPATHLEN+1]; + Py_ssize_t len; + struct _stat wstatbuf; + + len = PyUnicode_AsWideChar((PyUnicodeObject*)path, wpath, + sizeof(wpath) / sizeof(wpath[0])); + if (len == -1) { + PyErr_Clear(); + return -1; + } + err = _wstat(wpath, &statbuf); + if (!err) + statbuf->st_mode = wstatbuf.st_mode; + return err; +#else + PyObject *bytes = PyUnicode_EncodeFSDefault(path); + if (bytes == NULL) { + PyErr_Clear(); + return -1; + } + err = stat(PyBytes_AS_STRING(bytes), statbuf); + Py_DECREF(bytes); + return err; +#endif +} + /* Helper to look for __init__.py or __init__.py[co] in potential package */ static int find_init_module(char *buf)