Patch 594001: PEP 277 - Unicode file name support for Windows NT.
This commit is contained in:
parent
eb287a2662
commit
c2e85bd4e2
|
@ -81,16 +81,37 @@ PyAPI_DATA(PyObject *) PyExc_FutureWarning;
|
||||||
PyAPI_FUNC(int) PyErr_BadArgument(void);
|
PyAPI_FUNC(int) PyErr_BadArgument(void);
|
||||||
PyAPI_FUNC(PyObject *) PyErr_NoMemory(void);
|
PyAPI_FUNC(PyObject *) PyErr_NoMemory(void);
|
||||||
PyAPI_FUNC(PyObject *) PyErr_SetFromErrno(PyObject *);
|
PyAPI_FUNC(PyObject *) PyErr_SetFromErrno(PyObject *);
|
||||||
|
PyAPI_FUNC(PyObject *) PyErr_SetFromErrnoWithFilenameObject(
|
||||||
|
PyObject *, PyObject *);
|
||||||
PyAPI_FUNC(PyObject *) PyErr_SetFromErrnoWithFilename(PyObject *, char *);
|
PyAPI_FUNC(PyObject *) PyErr_SetFromErrnoWithFilename(PyObject *, char *);
|
||||||
|
#ifdef Py_WIN_WIDE_FILENAMES
|
||||||
|
PyAPI_FUNC(PyObject *) PyErr_SetFromErrnoWithUnicodeFilename(
|
||||||
|
PyObject *, Py_UNICODE *);
|
||||||
|
#endif /* Py_WIN_WIDE_FILENAMES */
|
||||||
|
|
||||||
PyAPI_FUNC(PyObject *) PyErr_Format(PyObject *, const char *, ...)
|
PyAPI_FUNC(PyObject *) PyErr_Format(PyObject *, const char *, ...)
|
||||||
Py_GCC_ATTRIBUTE((format(printf, 2, 3)));
|
Py_GCC_ATTRIBUTE((format(printf, 2, 3)));
|
||||||
|
|
||||||
#ifdef MS_WINDOWS
|
#ifdef MS_WINDOWS
|
||||||
PyAPI_FUNC(PyObject *) PyErr_SetFromWindowsErrWithFilename(int, const char *);
|
PyAPI_FUNC(PyObject *) PyErr_SetFromWindowsErrWithFilenameObject(
|
||||||
|
int, const char *);
|
||||||
|
PyAPI_FUNC(PyObject *) PyErr_SetFromWindowsErrWithFilename(
|
||||||
|
int, const char *);
|
||||||
|
#ifdef Py_WIN_WIDE_FILENAMES
|
||||||
|
PyAPI_FUNC(PyObject *) PyErr_SetFromWindowsErrWithUnicodeFilename(
|
||||||
|
int, const Py_UNICODE *);
|
||||||
|
#endif /* Py_WIN_WIDE_FILENAMES */
|
||||||
PyAPI_FUNC(PyObject *) PyErr_SetFromWindowsErr(int);
|
PyAPI_FUNC(PyObject *) PyErr_SetFromWindowsErr(int);
|
||||||
|
PyAPI_FUNC(PyObject *) PyErr_SetExcFromWindowsErrWithFilenameObject(
|
||||||
|
PyObject *,int, PyObject *);
|
||||||
PyAPI_FUNC(PyObject *) PyErr_SetExcFromWindowsErrWithFilename(
|
PyAPI_FUNC(PyObject *) PyErr_SetExcFromWindowsErrWithFilename(
|
||||||
PyObject *,int, const char *);
|
PyObject *,int, const char *);
|
||||||
|
#ifdef Py_WIN_WIDE_FILENAMES
|
||||||
|
PyAPI_FUNC(PyObject *) PyErr_SetExcFromWindowsErrWithUnicodeFilename(
|
||||||
|
PyObject *,int, const Py_UNICODE *);
|
||||||
|
#endif /* Py_WIN_WIDE_FILENAMES */
|
||||||
PyAPI_FUNC(PyObject *) PyErr_SetExcFromWindowsErr(PyObject *, int);
|
PyAPI_FUNC(PyObject *) PyErr_SetExcFromWindowsErr(PyObject *, int);
|
||||||
#endif
|
#endif /* MS_WINDOWS */
|
||||||
|
|
||||||
/* Export the old function so that the existing API remains available: */
|
/* Export the old function so that the existing API remains available: */
|
||||||
PyAPI_FUNC(void) PyErr_BadInternalCall(void);
|
PyAPI_FUNC(void) PyErr_BadInternalCall(void);
|
||||||
|
|
|
@ -40,6 +40,10 @@ os.chmod(TESTFN_ENCODED, 0777)
|
||||||
os.chmod(TESTFN_UNICODE, 0777)
|
os.chmod(TESTFN_UNICODE, 0777)
|
||||||
|
|
||||||
# Test rename
|
# Test rename
|
||||||
|
try:
|
||||||
|
os.unlink(TESTFN_ENCODED + ".new")
|
||||||
|
except os.error:
|
||||||
|
pass
|
||||||
os.rename(TESTFN_ENCODED, TESTFN_ENCODED + ".new")
|
os.rename(TESTFN_ENCODED, TESTFN_ENCODED + ".new")
|
||||||
os.rename(TESTFN_UNICODE+".new", TESTFN_ENCODED)
|
os.rename(TESTFN_UNICODE+".new", TESTFN_ENCODED)
|
||||||
|
|
||||||
|
|
|
@ -367,6 +367,15 @@ posix_error_with_filename(char* name)
|
||||||
return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
|
return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef Py_WIN_WIDE_FILENAMES
|
||||||
|
static PyObject *
|
||||||
|
posix_error_with_unicode_filename(Py_UNICODE* name)
|
||||||
|
{
|
||||||
|
return PyErr_SetFromErrnoWithUnicodeFilename(PyExc_OSError, name);
|
||||||
|
}
|
||||||
|
#endif /* Py_WIN_WIDE_FILENAMES */
|
||||||
|
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
posix_error_with_allocated_filename(char* name)
|
posix_error_with_allocated_filename(char* name)
|
||||||
{
|
{
|
||||||
|
@ -390,6 +399,40 @@ win32_error(char* function, char* filename)
|
||||||
else
|
else
|
||||||
return PyErr_SetFromWindowsErr(errno);
|
return PyErr_SetFromWindowsErr(errno);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef Py_WIN_WIDE_FILENAMES
|
||||||
|
static PyObject *
|
||||||
|
win32_error_unicode(char* function, Py_UNICODE* filename)
|
||||||
|
{
|
||||||
|
/* XXX - see win32_error for comments on 'function' */
|
||||||
|
errno = GetLastError();
|
||||||
|
if (filename)
|
||||||
|
return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename);
|
||||||
|
else
|
||||||
|
return PyErr_SetFromWindowsErr(errno);
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyObject *_PyUnicode_FromFileSystemEncodedObject(register PyObject *obj)
|
||||||
|
{
|
||||||
|
/* XXX Perhaps we should make this API an alias of
|
||||||
|
PyObject_Unicode() instead ?! */
|
||||||
|
if (PyUnicode_CheckExact(obj)) {
|
||||||
|
Py_INCREF(obj);
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
if (PyUnicode_Check(obj)) {
|
||||||
|
/* For a Unicode subtype that's not a Unicode object,
|
||||||
|
return a true Unicode object with the same data. */
|
||||||
|
return PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(obj),
|
||||||
|
PyUnicode_GET_SIZE(obj));
|
||||||
|
}
|
||||||
|
return PyUnicode_FromEncodedObject(obj,
|
||||||
|
Py_FileSystemDefaultEncoding,
|
||||||
|
"strict");
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* Py_WIN_WIDE_FILENAMES */
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(PYOS_OS2)
|
#if defined(PYOS_OS2)
|
||||||
|
@ -487,11 +530,50 @@ posix_fildes(PyObject *fdobj, int (*func)(int))
|
||||||
return Py_None;
|
return Py_None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef Py_WIN_WIDE_FILENAMES
|
||||||
|
static int
|
||||||
|
unicode_file_names(void)
|
||||||
|
{
|
||||||
|
static int canusewide = -1;
|
||||||
|
if (canusewide == -1) {
|
||||||
|
/* As per doc for ::GetVersion(), this is the correct test for
|
||||||
|
the Windows NT family. */
|
||||||
|
canusewide = (GetVersion() < 0x80000000) ? 1 : 0;
|
||||||
|
}
|
||||||
|
return canusewide;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
posix_1str(PyObject *args, char *format, int (*func)(const char*))
|
posix_1str(PyObject *args, char *format, int (*func)(const char*),
|
||||||
|
char *wformat, int (*wfunc)(const Py_UNICODE*))
|
||||||
{
|
{
|
||||||
char *path1 = NULL;
|
char *path1 = NULL;
|
||||||
int res;
|
int res;
|
||||||
|
#ifdef Py_WIN_WIDE_FILENAMES
|
||||||
|
if (unicode_file_names()) {
|
||||||
|
PyUnicodeObject *po;
|
||||||
|
if (PyArg_ParseTuple(args, wformat, &po)) {
|
||||||
|
Py_BEGIN_ALLOW_THREADS
|
||||||
|
/* PyUnicode_AS_UNICODE OK without thread
|
||||||
|
lock as it is a simple dereference. */
|
||||||
|
res = (*wfunc)(PyUnicode_AS_UNICODE(po));
|
||||||
|
Py_END_ALLOW_THREADS
|
||||||
|
if (res < 0)
|
||||||
|
return posix_error();
|
||||||
|
Py_INCREF(Py_None);
|
||||||
|
return Py_None;
|
||||||
|
}
|
||||||
|
/* Drop the argument parsing error as narrow
|
||||||
|
strings are also valid. */
|
||||||
|
PyErr_Clear();
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
/* Platforms that don't support Unicode filenames
|
||||||
|
shouldn't be passing these extra params */
|
||||||
|
assert(wformat==NULL && wfunc == NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, format,
|
if (!PyArg_ParseTuple(args, format,
|
||||||
Py_FileSystemDefaultEncoding, &path1))
|
Py_FileSystemDefaultEncoding, &path1))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -506,11 +588,54 @@ posix_1str(PyObject *args, char *format, int (*func)(const char*))
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
posix_2str(PyObject *args, char *format,
|
posix_2str(PyObject *args,
|
||||||
int (*func)(const char *, const char *))
|
char *format,
|
||||||
|
int (*func)(const char *, const char *),
|
||||||
|
char *wformat,
|
||||||
|
int (*wfunc)(const Py_UNICODE *, const Py_UNICODE *))
|
||||||
{
|
{
|
||||||
char *path1 = NULL, *path2 = NULL;
|
char *path1 = NULL, *path2 = NULL;
|
||||||
int res;
|
int res;
|
||||||
|
#ifdef Py_WIN_WIDE_FILENAMES
|
||||||
|
if (unicode_file_names()) {
|
||||||
|
PyObject *po1;
|
||||||
|
PyObject *po2;
|
||||||
|
if (PyArg_ParseTuple(args, wformat, &po1, &po2)) {
|
||||||
|
if (PyUnicode_Check(po1) || PyUnicode_Check(po2)) {
|
||||||
|
PyObject *wpath1;
|
||||||
|
PyObject *wpath2;
|
||||||
|
wpath1 = _PyUnicode_FromFileSystemEncodedObject(po1);
|
||||||
|
wpath2 = _PyUnicode_FromFileSystemEncodedObject(po2);
|
||||||
|
if (!wpath1 || !wpath2) {
|
||||||
|
Py_XDECREF(wpath1);
|
||||||
|
Py_XDECREF(wpath2);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
Py_BEGIN_ALLOW_THREADS
|
||||||
|
/* PyUnicode_AS_UNICODE OK without thread
|
||||||
|
lock as it is a simple dereference. */
|
||||||
|
res = (*wfunc)(PyUnicode_AS_UNICODE(wpath1),
|
||||||
|
PyUnicode_AS_UNICODE(wpath2));
|
||||||
|
Py_END_ALLOW_THREADS
|
||||||
|
Py_XDECREF(wpath1);
|
||||||
|
Py_XDECREF(wpath2);
|
||||||
|
if (res != 0)
|
||||||
|
return posix_error();
|
||||||
|
Py_INCREF(Py_None);
|
||||||
|
return Py_None;
|
||||||
|
}
|
||||||
|
/* Else flow through as neither is Unicode. */
|
||||||
|
}
|
||||||
|
/* Drop the argument parsing error as narrow
|
||||||
|
strings are also valid. */
|
||||||
|
PyErr_Clear();
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
/* Platforms that don't support Unicode filenames
|
||||||
|
shouldn't be passing these extra params */
|
||||||
|
assert(wformat==NULL && wfunc == NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, format,
|
if (!PyArg_ParseTuple(args, format,
|
||||||
Py_FileSystemDefaultEncoding, &path1,
|
Py_FileSystemDefaultEncoding, &path1,
|
||||||
Py_FileSystemDefaultEncoding, &path2))
|
Py_FileSystemDefaultEncoding, &path2))
|
||||||
|
@ -692,8 +817,11 @@ _pystat_fromstructstat(STRUCT_STAT st)
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
posix_do_stat(PyObject *self, PyObject *args, char *format,
|
posix_do_stat(PyObject *self, PyObject *args,
|
||||||
int (*statfunc)(const char *, STRUCT_STAT *))
|
char *format,
|
||||||
|
int (*statfunc)(const char *, STRUCT_STAT *),
|
||||||
|
char *wformat,
|
||||||
|
int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
|
||||||
{
|
{
|
||||||
STRUCT_STAT st;
|
STRUCT_STAT st;
|
||||||
char *path = NULL; /* pass this to stat; do not free() it */
|
char *path = NULL; /* pass this to stat; do not free() it */
|
||||||
|
@ -705,6 +833,50 @@ posix_do_stat(PyObject *self, PyObject *args, char *format,
|
||||||
char pathcopy[MAX_PATH];
|
char pathcopy[MAX_PATH];
|
||||||
#endif /* MS_WINDOWS */
|
#endif /* MS_WINDOWS */
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef Py_WIN_WIDE_FILENAMES
|
||||||
|
/* If on wide-character-capable OS see if argument
|
||||||
|
is Unicode and if so use wide API. */
|
||||||
|
if (unicode_file_names()) {
|
||||||
|
PyUnicodeObject *po;
|
||||||
|
if (PyArg_ParseTuple(args, wformat, &po)) {
|
||||||
|
Py_UNICODE wpath[MAX_PATH+1];
|
||||||
|
pathlen = wcslen(PyUnicode_AS_UNICODE(po));
|
||||||
|
/* the library call can blow up if the file name is too long! */
|
||||||
|
if (pathlen > MAX_PATH) {
|
||||||
|
errno = ENAMETOOLONG;
|
||||||
|
return posix_error();
|
||||||
|
}
|
||||||
|
wcscpy(wpath, PyUnicode_AS_UNICODE(po));
|
||||||
|
/* Remove trailing slash or backslash, unless it's the current
|
||||||
|
drive root (/ or \) or a specific drive's root (like c:\ or c:/).
|
||||||
|
*/
|
||||||
|
if (pathlen > 0 &&
|
||||||
|
(wpath[pathlen-1]== L'\\' || wpath[pathlen-1] == L'/')) {
|
||||||
|
/* It does end with a slash -- exempt the root drive cases. */
|
||||||
|
/* XXX UNC root drives should also be exempted? */
|
||||||
|
if (pathlen == 1 || (pathlen == 3 && wpath[1] == L':'))
|
||||||
|
/* leave it alone */;
|
||||||
|
else {
|
||||||
|
/* nuke the trailing backslash */
|
||||||
|
wpath[pathlen-1] = L'\0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Py_BEGIN_ALLOW_THREADS
|
||||||
|
/* PyUnicode_AS_UNICODE result OK without
|
||||||
|
thread lock as it is a simple dereference. */
|
||||||
|
res = wstatfunc(wpath, &st);
|
||||||
|
Py_END_ALLOW_THREADS
|
||||||
|
if (res != 0)
|
||||||
|
return posix_error_with_unicode_filename(wpath);
|
||||||
|
return _pystat_fromstructstat(st);
|
||||||
|
}
|
||||||
|
/* Drop the argument parsing error as narrow strings
|
||||||
|
are also valid. */
|
||||||
|
PyErr_Clear();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, format,
|
if (!PyArg_ParseTuple(args, format,
|
||||||
Py_FileSystemDefaultEncoding, &path))
|
Py_FileSystemDefaultEncoding, &path))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -839,10 +1011,12 @@ Change the current working directory to the specified path.");
|
||||||
static PyObject *
|
static PyObject *
|
||||||
posix_chdir(PyObject *self, PyObject *args)
|
posix_chdir(PyObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
#if defined(PYOS_OS2) && defined(PYCC_GCC)
|
#ifdef MS_WINDOWS
|
||||||
return posix_1str(args, "et:chdir", _chdir2);
|
return posix_1str(args, "et:chdir", chdir, "U:chdir", _wchdir);
|
||||||
|
#elif defined(PYOS_OS2) && defined(PYCC_GCC)
|
||||||
|
return posix_1str(args, "et:chdir", _chdir2, NULL, NULL);
|
||||||
#else
|
#else
|
||||||
return posix_1str(args, "et:chdir", chdir);
|
return posix_1str(args, "et:chdir", chdir, NULL, NULL);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -892,7 +1066,7 @@ Change root directory to path.");
|
||||||
static PyObject *
|
static PyObject *
|
||||||
posix_chroot(PyObject *self, PyObject *args)
|
posix_chroot(PyObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
return posix_1str(args, "et:chroot", chroot);
|
return posix_1str(args, "et:chroot", chroot, NULL, NULL);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1004,6 +1178,43 @@ posix_getcwd(PyObject *self, PyObject *args)
|
||||||
return posix_error();
|
return posix_error();
|
||||||
return PyString_FromString(buf);
|
return PyString_FromString(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PyDoc_STRVAR(posix_getcwdu__doc__,
|
||||||
|
"getcwdu() -> path\n\n\
|
||||||
|
Return a unicode string representing the current working directory.");
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
posix_getcwdu(PyObject *self, PyObject *args)
|
||||||
|
{
|
||||||
|
char buf[1026];
|
||||||
|
char *res;
|
||||||
|
if (!PyArg_ParseTuple(args, ":getcwd"))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
#ifdef Py_WIN_WIDE_FILENAMES
|
||||||
|
if (unicode_file_names()) {
|
||||||
|
wchar_t *wres;
|
||||||
|
wchar_t wbuf[1026];
|
||||||
|
Py_BEGIN_ALLOW_THREADS
|
||||||
|
wres = _wgetcwd(wbuf, sizeof wbuf/ sizeof wbuf[0]);
|
||||||
|
Py_END_ALLOW_THREADS
|
||||||
|
if (wres == NULL)
|
||||||
|
return posix_error();
|
||||||
|
return PyUnicode_FromWideChar(wbuf, wcslen(wbuf));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Py_BEGIN_ALLOW_THREADS
|
||||||
|
#if defined(PYOS_OS2) && defined(PYCC_GCC)
|
||||||
|
res = _getcwd2(buf, sizeof buf);
|
||||||
|
#else
|
||||||
|
res = getcwd(buf, sizeof buf);
|
||||||
|
#endif
|
||||||
|
Py_END_ALLOW_THREADS
|
||||||
|
if (res == NULL)
|
||||||
|
return posix_error();
|
||||||
|
return PyUnicode_Decode(buf, strlen(buf), Py_FileSystemDefaultEncoding,"strict");
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@ -1015,7 +1226,7 @@ Create a hard link to a file.");
|
||||||
static PyObject *
|
static PyObject *
|
||||||
posix_link(PyObject *self, PyObject *args)
|
posix_link(PyObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
return posix_2str(args, "etet:link", link);
|
return posix_2str(args, "etet:link", link, NULL, NULL);
|
||||||
}
|
}
|
||||||
#endif /* HAVE_LINK */
|
#endif /* HAVE_LINK */
|
||||||
|
|
||||||
|
@ -1044,6 +1255,66 @@ posix_listdir(PyObject *self, PyObject *args)
|
||||||
char *bufptr = namebuf;
|
char *bufptr = namebuf;
|
||||||
int len = sizeof(namebuf)/sizeof(namebuf[0]);
|
int len = sizeof(namebuf)/sizeof(namebuf[0]);
|
||||||
|
|
||||||
|
#ifdef Py_WIN_WIDE_FILENAMES
|
||||||
|
/* If on wide-character-capable OS see if argument
|
||||||
|
is Unicode and if so use wide API. */
|
||||||
|
if (unicode_file_names()) {
|
||||||
|
PyUnicodeObject *po;
|
||||||
|
if (PyArg_ParseTuple(args, "U:listdir", &po)) {
|
||||||
|
WIN32_FIND_DATAW wFileData;
|
||||||
|
Py_UNICODE wnamebuf[MAX_PATH*2+5];
|
||||||
|
Py_UNICODE wch;
|
||||||
|
wcsncpy(wnamebuf, PyUnicode_AS_UNICODE(po), MAX_PATH);
|
||||||
|
wnamebuf[MAX_PATH] = L'\0';
|
||||||
|
len = wcslen(wnamebuf);
|
||||||
|
wch = (len > 0) ? wnamebuf[len-1] : L'\0';
|
||||||
|
if (wch != L'/' && wch != L'\\' && wch != L':')
|
||||||
|
wnamebuf[len++] = L'/';
|
||||||
|
wcscpy(wnamebuf + len, L"*.*");
|
||||||
|
if ((d = PyList_New(0)) == NULL)
|
||||||
|
return NULL;
|
||||||
|
hFindFile = FindFirstFileW(wnamebuf, &wFileData);
|
||||||
|
if (hFindFile == INVALID_HANDLE_VALUE) {
|
||||||
|
errno = GetLastError();
|
||||||
|
if (errno == ERROR_FILE_NOT_FOUND) {
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
Py_DECREF(d);
|
||||||
|
return win32_error_unicode("FindFirstFileW", wnamebuf);
|
||||||
|
}
|
||||||
|
do {
|
||||||
|
if (wFileData.cFileName[0] == L'.' &&
|
||||||
|
(wFileData.cFileName[1] == L'\0' ||
|
||||||
|
wFileData.cFileName[1] == L'.' &&
|
||||||
|
wFileData.cFileName[2] == L'\0'))
|
||||||
|
continue;
|
||||||
|
v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
|
||||||
|
if (v == NULL) {
|
||||||
|
Py_DECREF(d);
|
||||||
|
d = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (PyList_Append(d, v) != 0) {
|
||||||
|
Py_DECREF(v);
|
||||||
|
Py_DECREF(d);
|
||||||
|
d = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Py_DECREF(v);
|
||||||
|
} while (FindNextFileW(hFindFile, &wFileData) == TRUE);
|
||||||
|
|
||||||
|
if (FindClose(hFindFile) == FALSE) {
|
||||||
|
Py_DECREF(d);
|
||||||
|
return win32_error_unicode("FindClose", wnamebuf);
|
||||||
|
}
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
/* Drop the argument parsing error as narrow strings
|
||||||
|
are also valid. */
|
||||||
|
PyErr_Clear();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "et#:listdir",
|
if (!PyArg_ParseTuple(args, "et#:listdir",
|
||||||
Py_FileSystemDefaultEncoding, &bufptr, &len))
|
Py_FileSystemDefaultEncoding, &bufptr, &len))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -1061,7 +1332,8 @@ posix_listdir(PyObject *self, PyObject *args)
|
||||||
if (hFindFile == INVALID_HANDLE_VALUE) {
|
if (hFindFile == INVALID_HANDLE_VALUE) {
|
||||||
errno = GetLastError();
|
errno = GetLastError();
|
||||||
if (errno == ERROR_FILE_NOT_FOUND)
|
if (errno == ERROR_FILE_NOT_FOUND)
|
||||||
return PyList_New(0);
|
return d;
|
||||||
|
Py_DECREF(d);
|
||||||
return win32_error("FindFirstFile", namebuf);
|
return win32_error("FindFirstFile", namebuf);
|
||||||
}
|
}
|
||||||
do {
|
do {
|
||||||
|
@ -1085,8 +1357,10 @@ posix_listdir(PyObject *self, PyObject *args)
|
||||||
Py_DECREF(v);
|
Py_DECREF(v);
|
||||||
} while (FindNextFile(hFindFile, &FileData) == TRUE);
|
} while (FindNextFile(hFindFile, &FileData) == TRUE);
|
||||||
|
|
||||||
if (FindClose(hFindFile) == FALSE)
|
if (FindClose(hFindFile) == FALSE) {
|
||||||
|
Py_DECREF(d);
|
||||||
return win32_error("FindClose", namebuf);
|
return win32_error("FindClose", namebuf);
|
||||||
|
}
|
||||||
|
|
||||||
return d;
|
return d;
|
||||||
|
|
||||||
|
@ -1213,6 +1487,23 @@ posix__getfullpathname(PyObject *self, PyObject *args)
|
||||||
int insize = sizeof(inbuf)/sizeof(inbuf[0]);
|
int insize = sizeof(inbuf)/sizeof(inbuf[0]);
|
||||||
char outbuf[MAX_PATH*2];
|
char outbuf[MAX_PATH*2];
|
||||||
char *temp;
|
char *temp;
|
||||||
|
#ifdef Py_WIN_WIDE_FILENAMES
|
||||||
|
if (unicode_file_names()) {
|
||||||
|
PyUnicodeObject *po;
|
||||||
|
if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
|
||||||
|
Py_UNICODE woutbuf[MAX_PATH*2];
|
||||||
|
Py_UNICODE *wtemp;
|
||||||
|
if (!GetFullPathNameW(PyUnicode_AS_UNICODE(po),
|
||||||
|
sizeof(woutbuf)/sizeof(woutbuf[0]),
|
||||||
|
woutbuf, &wtemp))
|
||||||
|
return win32_error("GetFullPathName", "");
|
||||||
|
return PyUnicode_FromUnicode(woutbuf, wcslen(woutbuf));
|
||||||
|
}
|
||||||
|
/* Drop the argument parsing error as narrow strings
|
||||||
|
are also valid. */
|
||||||
|
PyErr_Clear();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
|
if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
|
||||||
Py_FileSystemDefaultEncoding, &inbufp,
|
Py_FileSystemDefaultEncoding, &inbufp,
|
||||||
&insize))
|
&insize))
|
||||||
|
@ -1234,6 +1525,27 @@ posix_mkdir(PyObject *self, PyObject *args)
|
||||||
int res;
|
int res;
|
||||||
char *path = NULL;
|
char *path = NULL;
|
||||||
int mode = 0777;
|
int mode = 0777;
|
||||||
|
|
||||||
|
#ifdef Py_WIN_WIDE_FILENAMES
|
||||||
|
if (unicode_file_names()) {
|
||||||
|
PyUnicodeObject *po;
|
||||||
|
if (PyArg_ParseTuple(args, "U|i:mkdir", &po)) {
|
||||||
|
Py_BEGIN_ALLOW_THREADS
|
||||||
|
/* PyUnicode_AS_UNICODE OK without thread lock as
|
||||||
|
it is a simple dereference. */
|
||||||
|
res = _wmkdir(PyUnicode_AS_UNICODE(po));
|
||||||
|
Py_END_ALLOW_THREADS
|
||||||
|
if (res < 0)
|
||||||
|
return posix_error();
|
||||||
|
Py_INCREF(Py_None);
|
||||||
|
return Py_None;
|
||||||
|
}
|
||||||
|
/* Drop the argument parsing error as narrow strings
|
||||||
|
are also valid. */
|
||||||
|
PyErr_Clear();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "et|i:mkdir",
|
if (!PyArg_ParseTuple(args, "et|i:mkdir",
|
||||||
Py_FileSystemDefaultEncoding, &path, &mode))
|
Py_FileSystemDefaultEncoding, &path, &mode))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -1302,7 +1614,11 @@ Rename a file or directory.");
|
||||||
static PyObject *
|
static PyObject *
|
||||||
posix_rename(PyObject *self, PyObject *args)
|
posix_rename(PyObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
return posix_2str(args, "etet:rename", rename);
|
#ifdef MS_WINDOWS
|
||||||
|
return posix_2str(args, "etet:rename", rename, "OO:rename", _wrename);
|
||||||
|
#else
|
||||||
|
return posix_2str(args, "etet:rename", rename, NULL, NULL);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1313,7 +1629,11 @@ Remove a directory.");
|
||||||
static PyObject *
|
static PyObject *
|
||||||
posix_rmdir(PyObject *self, PyObject *args)
|
posix_rmdir(PyObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
return posix_1str(args, "et:rmdir", rmdir);
|
#ifdef MS_WINDOWS
|
||||||
|
return posix_1str(args, "et:rmdir", rmdir, "U:rmdir", _wrmdir);
|
||||||
|
#else
|
||||||
|
return posix_1str(args, "et:rmdir", rmdir, NULL, NULL);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1324,7 +1644,11 @@ Perform a stat system call on the given path.");
|
||||||
static PyObject *
|
static PyObject *
|
||||||
posix_stat(PyObject *self, PyObject *args)
|
posix_stat(PyObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
return posix_do_stat(self, args, "et:stat", STAT);
|
#ifdef MS_WINDOWS
|
||||||
|
return posix_do_stat(self, args, "et:stat", STAT, "U:stat", _wstati64);
|
||||||
|
#else
|
||||||
|
return posix_do_stat(self, args, "et:stat", STAT, NULL, NULL);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1376,7 +1700,11 @@ Remove a file (same as unlink(path)).");
|
||||||
static PyObject *
|
static PyObject *
|
||||||
posix_unlink(PyObject *self, PyObject *args)
|
posix_unlink(PyObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
return posix_1str(args, "et:remove", unlink);
|
#ifdef MS_WINDOWS
|
||||||
|
return posix_1str(args, "et:remove", unlink, "U:remove", _wunlink);
|
||||||
|
#else
|
||||||
|
return posix_1str(args, "et:remove", unlink, NULL, NULL);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -4150,9 +4478,13 @@ static PyObject *
|
||||||
posix_lstat(PyObject *self, PyObject *args)
|
posix_lstat(PyObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_LSTAT
|
#ifdef HAVE_LSTAT
|
||||||
return posix_do_stat(self, args, "et:lstat", lstat);
|
return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL);
|
||||||
#else /* !HAVE_LSTAT */
|
#else /* !HAVE_LSTAT */
|
||||||
return posix_do_stat(self, args, "et:lstat", STAT);
|
#ifdef MS_WINDOWS
|
||||||
|
return posix_do_stat(self, args, "et:lstat", STAT, "u:lstat", _wstati64);
|
||||||
|
#else
|
||||||
|
return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL);
|
||||||
|
#endif
|
||||||
#endif /* !HAVE_LSTAT */
|
#endif /* !HAVE_LSTAT */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4188,7 +4520,7 @@ Create a symbolic link.");
|
||||||
static PyObject *
|
static PyObject *
|
||||||
posix_symlink(PyObject *self, PyObject *args)
|
posix_symlink(PyObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
return posix_2str(args, "etet:symlink", symlink);
|
return posix_2str(args, "etet:symlink", symlink, NULL, NULL);
|
||||||
}
|
}
|
||||||
#endif /* HAVE_SYMLINK */
|
#endif /* HAVE_SYMLINK */
|
||||||
|
|
||||||
|
@ -4369,6 +4701,26 @@ posix_open(PyObject *self, PyObject *args)
|
||||||
int flag;
|
int flag;
|
||||||
int mode = 0777;
|
int mode = 0777;
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
|
#ifdef MS_WINDOWS
|
||||||
|
if (unicode_file_names()) {
|
||||||
|
PyUnicodeObject *po;
|
||||||
|
if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
|
||||||
|
Py_BEGIN_ALLOW_THREADS
|
||||||
|
/* PyUnicode_AS_UNICODE OK without thread
|
||||||
|
lock as it is a simple dereference. */
|
||||||
|
fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
|
||||||
|
Py_END_ALLOW_THREADS
|
||||||
|
if (fd < 0)
|
||||||
|
return posix_error();
|
||||||
|
return PyInt_FromLong((long)fd);
|
||||||
|
}
|
||||||
|
/* Drop the argument parsing error as narrow strings
|
||||||
|
are also valid. */
|
||||||
|
PyErr_Clear();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "eti|i",
|
if (!PyArg_ParseTuple(args, "eti|i",
|
||||||
Py_FileSystemDefaultEncoding, &file,
|
Py_FileSystemDefaultEncoding, &file,
|
||||||
&flag, &mode))
|
&flag, &mode))
|
||||||
|
@ -6341,6 +6693,7 @@ static PyMethodDef posix_methods[] = {
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_GETCWD
|
#ifdef HAVE_GETCWD
|
||||||
{"getcwd", posix_getcwd, METH_VARARGS, posix_getcwd__doc__},
|
{"getcwd", posix_getcwd, METH_VARARGS, posix_getcwd__doc__},
|
||||||
|
{"getcwdu", posix_getcwdu, METH_VARARGS, posix_getcwdu__doc__},
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_LINK
|
#ifdef HAVE_LINK
|
||||||
{"link", posix_link, METH_VARARGS, posix_link__doc__},
|
{"link", posix_link, METH_VARARGS, posix_link__doc__},
|
||||||
|
|
|
@ -15,6 +15,12 @@
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
/* Need GetVersion to see if on NT so safe to use _wfopen */
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#include <windows.h>
|
||||||
|
#endif /* _MSC_VER */
|
||||||
|
|
||||||
#ifdef macintosh
|
#ifdef macintosh
|
||||||
#ifdef USE_GUSI
|
#ifdef USE_GUSI
|
||||||
#define HAVE_FTRUNCATE
|
#define HAVE_FTRUNCATE
|
||||||
|
@ -102,7 +108,7 @@ dircheck(PyFileObject* f)
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
fill_file_fields(PyFileObject *f, FILE *fp, char *name, char *mode,
|
fill_file_fields(PyFileObject *f, FILE *fp, char *name, char *mode,
|
||||||
int (*close)(FILE *))
|
int (*close)(FILE *), PyObject *wname)
|
||||||
{
|
{
|
||||||
assert(f != NULL);
|
assert(f != NULL);
|
||||||
assert(PyFile_Check(f));
|
assert(PyFile_Check(f));
|
||||||
|
@ -110,7 +116,10 @@ fill_file_fields(PyFileObject *f, FILE *fp, char *name, char *mode,
|
||||||
|
|
||||||
Py_DECREF(f->f_name);
|
Py_DECREF(f->f_name);
|
||||||
Py_DECREF(f->f_mode);
|
Py_DECREF(f->f_mode);
|
||||||
f->f_name = PyString_FromString(name);
|
if (wname)
|
||||||
|
f->f_name = PyUnicode_FromObject(wname);
|
||||||
|
else
|
||||||
|
f->f_name = PyString_FromString(name);
|
||||||
f->f_mode = PyString_FromString(mode);
|
f->f_mode = PyString_FromString(mode);
|
||||||
|
|
||||||
f->f_close = close;
|
f->f_close = close;
|
||||||
|
@ -135,7 +144,12 @@ open_the_file(PyFileObject *f, char *name, char *mode)
|
||||||
{
|
{
|
||||||
assert(f != NULL);
|
assert(f != NULL);
|
||||||
assert(PyFile_Check(f));
|
assert(PyFile_Check(f));
|
||||||
|
#ifdef MS_WINDOWS
|
||||||
|
/* windows ignores the passed name in order to support Unicode */
|
||||||
|
assert(f->f_name != NULL);
|
||||||
|
#else
|
||||||
assert(name != NULL);
|
assert(name != NULL);
|
||||||
|
#endif
|
||||||
assert(mode != NULL);
|
assert(mode != NULL);
|
||||||
assert(f->f_fp == NULL);
|
assert(f->f_fp == NULL);
|
||||||
|
|
||||||
|
@ -156,7 +170,6 @@ open_the_file(PyFileObject *f, char *name, char *mode)
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
Py_BEGIN_ALLOW_THREADS
|
|
||||||
#ifdef WITH_UNIVERSAL_NEWLINES
|
#ifdef WITH_UNIVERSAL_NEWLINES
|
||||||
if (strcmp(mode, "U") == 0 || strcmp(mode, "rU") == 0)
|
if (strcmp(mode, "U") == 0 || strcmp(mode, "rU") == 0)
|
||||||
mode = "rb";
|
mode = "rb";
|
||||||
|
@ -168,8 +181,26 @@ open_the_file(PyFileObject *f, char *name, char *mode)
|
||||||
if (strcmp(mode, "U") == 0 || strcmp(mode, "rU") == 0)
|
if (strcmp(mode, "U") == 0 || strcmp(mode, "rU") == 0)
|
||||||
mode = "r";
|
mode = "r";
|
||||||
#endif
|
#endif
|
||||||
f->f_fp = fopen(name, mode);
|
#ifdef MS_WINDOWS
|
||||||
Py_END_ALLOW_THREADS
|
if (PyUnicode_Check(f->f_name)) {
|
||||||
|
PyObject *wmode;
|
||||||
|
wmode = PyUnicode_DecodeASCII(mode, strlen(mode), NULL);
|
||||||
|
if (f->f_name && wmode) {
|
||||||
|
Py_BEGIN_ALLOW_THREADS
|
||||||
|
/* PyUnicode_AS_UNICODE OK without thread
|
||||||
|
lock as it is a simple dereference. */
|
||||||
|
f->f_fp = _wfopen(PyUnicode_AS_UNICODE(f->f_name),
|
||||||
|
PyUnicode_AS_UNICODE(wmode));
|
||||||
|
Py_END_ALLOW_THREADS
|
||||||
|
}
|
||||||
|
Py_XDECREF(wmode);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (NULL == f->f_fp && NULL != name) {
|
||||||
|
Py_BEGIN_ALLOW_THREADS
|
||||||
|
f->f_fp = fopen(name, mode);
|
||||||
|
Py_END_ALLOW_THREADS
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (f->f_fp == NULL) {
|
if (f->f_fp == NULL) {
|
||||||
#ifdef NO_FOPEN_ERRNO
|
#ifdef NO_FOPEN_ERRNO
|
||||||
|
@ -201,7 +232,11 @@ open_the_file(PyFileObject *f, char *name, char *mode)
|
||||||
PyErr_Format(PyExc_IOError, "invalid mode: %s",
|
PyErr_Format(PyExc_IOError, "invalid mode: %s",
|
||||||
mode);
|
mode);
|
||||||
else
|
else
|
||||||
|
#ifdef MS_WINDOWS
|
||||||
|
PyErr_SetFromErrnoWithFilenameObject(PyExc_IOError, f->f_name);
|
||||||
|
#else
|
||||||
PyErr_SetFromErrnoWithFilename(PyExc_IOError, name);
|
PyErr_SetFromErrnoWithFilename(PyExc_IOError, name);
|
||||||
|
#endif /* MS_WINDOWS */
|
||||||
f = NULL;
|
f = NULL;
|
||||||
}
|
}
|
||||||
if (f != NULL)
|
if (f != NULL)
|
||||||
|
@ -215,7 +250,7 @@ PyFile_FromFile(FILE *fp, char *name, char *mode, int (*close)(FILE *))
|
||||||
PyFileObject *f = (PyFileObject *)PyFile_Type.tp_new(&PyFile_Type,
|
PyFileObject *f = (PyFileObject *)PyFile_Type.tp_new(&PyFile_Type,
|
||||||
NULL, NULL);
|
NULL, NULL);
|
||||||
if (f != NULL) {
|
if (f != NULL) {
|
||||||
if (fill_file_fields(f, fp, name, mode, close) == NULL) {
|
if (fill_file_fields(f, fp, name, mode, close, NULL) == NULL) {
|
||||||
Py_DECREF(f);
|
Py_DECREF(f);
|
||||||
f = NULL;
|
f = NULL;
|
||||||
}
|
}
|
||||||
|
@ -293,11 +328,24 @@ file_dealloc(PyFileObject *f)
|
||||||
static PyObject *
|
static PyObject *
|
||||||
file_repr(PyFileObject *f)
|
file_repr(PyFileObject *f)
|
||||||
{
|
{
|
||||||
return PyString_FromFormat("<%s file '%s', mode '%s' at %p>",
|
if (PyUnicode_Check(f->f_name)) {
|
||||||
|
PyObject *ret = NULL;
|
||||||
|
PyObject *name;
|
||||||
|
name = PyUnicode_AsUnicodeEscapeString(f->f_name);
|
||||||
|
ret = PyString_FromFormat("<%s file u'%s', mode '%s' at %p>",
|
||||||
|
f->f_fp == NULL ? "closed" : "open",
|
||||||
|
PyString_AsString(name),
|
||||||
|
PyString_AsString(f->f_mode),
|
||||||
|
f);
|
||||||
|
Py_XDECREF(name);
|
||||||
|
return ret;
|
||||||
|
} else {
|
||||||
|
return PyString_FromFormat("<%s file '%s', mode '%s' at %p>",
|
||||||
f->f_fp == NULL ? "closed" : "open",
|
f->f_fp == NULL ? "closed" : "open",
|
||||||
PyString_AsString(f->f_name),
|
PyString_AsString(f->f_name),
|
||||||
PyString_AsString(f->f_mode),
|
PyString_AsString(f->f_mode),
|
||||||
f);
|
f);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
|
@ -1766,6 +1814,7 @@ file_init(PyObject *self, PyObject *args, PyObject *kwds)
|
||||||
char *name = NULL;
|
char *name = NULL;
|
||||||
char *mode = "r";
|
char *mode = "r";
|
||||||
int bufsize = -1;
|
int bufsize = -1;
|
||||||
|
int wideargument = 0;
|
||||||
|
|
||||||
assert(PyFile_Check(self));
|
assert(PyFile_Check(self));
|
||||||
if (foself->f_fp != NULL) {
|
if (foself->f_fp != NULL) {
|
||||||
|
@ -1776,12 +1825,33 @@ file_init(PyObject *self, PyObject *args, PyObject *kwds)
|
||||||
Py_DECREF(closeresult);
|
Py_DECREF(closeresult);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "et|si:file", kwlist,
|
#ifdef Py_WIN_WIDE_FILENAMES
|
||||||
Py_FileSystemDefaultEncoding, &name,
|
if (GetVersion() < 0x80000000) { /* On NT, so wide API available */
|
||||||
&mode, &bufsize))
|
PyObject *po;
|
||||||
return -1;
|
if (PyArg_ParseTupleAndKeywords(args, kwds, "U|si:file",
|
||||||
if (fill_file_fields(foself, NULL, name, mode, fclose) == NULL)
|
kwlist, &po, &mode, &bufsize)) {
|
||||||
goto Error;
|
wideargument = 1;
|
||||||
|
if (fill_file_fields(foself, NULL, name, mode,
|
||||||
|
fclose, po) == NULL)
|
||||||
|
goto Error;
|
||||||
|
} else {
|
||||||
|
/* Drop the argument parsing error as narrow
|
||||||
|
strings are also valid. */
|
||||||
|
PyErr_Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!wideargument) {
|
||||||
|
if (!PyArg_ParseTupleAndKeywords(args, kwds, "et|si:file", kwlist,
|
||||||
|
Py_FileSystemDefaultEncoding,
|
||||||
|
&name,
|
||||||
|
&mode, &bufsize))
|
||||||
|
return -1;
|
||||||
|
if (fill_file_fields(foself, NULL, name, mode,
|
||||||
|
fclose, NULL) == NULL)
|
||||||
|
goto Error;
|
||||||
|
}
|
||||||
if (open_the_file(foself, name, mode) == NULL)
|
if (open_the_file(foself, name, mode) == NULL)
|
||||||
goto Error;
|
goto Error;
|
||||||
PyFile_SetBufSize(self, bufsize);
|
PyFile_SetBufSize(self, bufsize);
|
||||||
|
|
|
@ -400,6 +400,10 @@ Py_NO_ENABLE_SHARED to find out. Also support MS_NO_COREDLL for b/w compat */
|
||||||
Include/unicodeobject.h). */
|
Include/unicodeobject.h). */
|
||||||
#if Py_UNICODE_SIZE == 2
|
#if Py_UNICODE_SIZE == 2
|
||||||
#define HAVE_USABLE_WCHAR_T
|
#define HAVE_USABLE_WCHAR_T
|
||||||
|
|
||||||
|
/* Define to indicate that the Python Unicode representation can be passed
|
||||||
|
as-is to Win32 Wide API. */
|
||||||
|
#define Py_WIN_WIDE_FILENAMES
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Use Python's own small-block memory-allocator. */
|
/* Use Python's own small-block memory-allocator. */
|
||||||
|
|
|
@ -259,7 +259,7 @@ PyErr_NoMemory(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
PyObject *
|
PyObject *
|
||||||
PyErr_SetFromErrnoWithFilename(PyObject *exc, char *filename)
|
PyErr_SetFromErrnoWithFilenameObject(PyObject *exc, PyObject *filenameObject)
|
||||||
{
|
{
|
||||||
PyObject *v;
|
PyObject *v;
|
||||||
char *s;
|
char *s;
|
||||||
|
@ -314,8 +314,8 @@ PyErr_SetFromErrnoWithFilename(PyObject *exc, char *filename)
|
||||||
}
|
}
|
||||||
#endif /* Unix/Windows */
|
#endif /* Unix/Windows */
|
||||||
#endif /* PLAN 9*/
|
#endif /* PLAN 9*/
|
||||||
if (filename != NULL)
|
if (filenameObject != NULL)
|
||||||
v = Py_BuildValue("(iss)", i, s, filename);
|
v = Py_BuildValue("(isO)", i, s, filenameObject);
|
||||||
else
|
else
|
||||||
v = Py_BuildValue("(is)", i, s);
|
v = Py_BuildValue("(is)", i, s);
|
||||||
if (v != NULL) {
|
if (v != NULL) {
|
||||||
|
@ -329,18 +329,40 @@ PyErr_SetFromErrnoWithFilename(PyObject *exc, char *filename)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PyObject *
|
||||||
|
PyErr_SetFromErrnoWithFilename(PyObject *exc, char *filename)
|
||||||
|
{
|
||||||
|
PyObject *name = filename ? PyString_FromString(filename) : NULL;
|
||||||
|
PyObject *result = PyErr_SetFromErrnoWithFilenameObject(exc, name);
|
||||||
|
Py_DECREF(name);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef Py_WIN_WIDE_FILENAMES
|
||||||
|
PyObject *
|
||||||
|
PyErr_SetFromErrnoWithUnicodeFilename(PyObject *exc, Py_UNICODE *filename)
|
||||||
|
{
|
||||||
|
PyObject *name = filename ?
|
||||||
|
PyUnicode_FromUnicode(filename, wcslen(filename)) :
|
||||||
|
NULL;
|
||||||
|
PyObject *result = PyErr_SetFromErrnoWithFilenameObject(exc, name);
|
||||||
|
Py_XDECREF(name);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
#endif /* Py_WIN_WIDE_FILENAMES */
|
||||||
|
|
||||||
PyObject *
|
PyObject *
|
||||||
PyErr_SetFromErrno(PyObject *exc)
|
PyErr_SetFromErrno(PyObject *exc)
|
||||||
{
|
{
|
||||||
return PyErr_SetFromErrnoWithFilename(exc, NULL);
|
return PyErr_SetFromErrnoWithFilenameObject(exc, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef MS_WINDOWS
|
#ifdef MS_WINDOWS
|
||||||
/* Windows specific error code handling */
|
/* Windows specific error code handling */
|
||||||
PyObject *PyErr_SetExcFromWindowsErrWithFilename(
|
PyObject *PyErr_SetExcFromWindowsErrWithFilenameObject(
|
||||||
PyObject *exc,
|
PyObject *exc,
|
||||||
int ierr,
|
int ierr,
|
||||||
const char *filename)
|
PyObject *filenameObject)
|
||||||
{
|
{
|
||||||
int len;
|
int len;
|
||||||
char *s;
|
char *s;
|
||||||
|
@ -362,8 +384,8 @@ PyObject *PyErr_SetExcFromWindowsErrWithFilename(
|
||||||
/* remove trailing cr/lf and dots */
|
/* remove trailing cr/lf and dots */
|
||||||
while (len > 0 && (s[len-1] <= ' ' || s[len-1] == '.'))
|
while (len > 0 && (s[len-1] <= ' ' || s[len-1] == '.'))
|
||||||
s[--len] = '\0';
|
s[--len] = '\0';
|
||||||
if (filename != NULL)
|
if (filenameObject != NULL)
|
||||||
v = Py_BuildValue("(iss)", err, s, filename);
|
v = Py_BuildValue("(isO)", err, s, filenameObject);
|
||||||
else
|
else
|
||||||
v = Py_BuildValue("(is)", err, s);
|
v = Py_BuildValue("(is)", err, s);
|
||||||
if (v != NULL) {
|
if (v != NULL) {
|
||||||
|
@ -374,6 +396,36 @@ PyObject *PyErr_SetExcFromWindowsErrWithFilename(
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PyObject *PyErr_SetExcFromWindowsErrWithFilename(
|
||||||
|
PyObject *exc,
|
||||||
|
int ierr,
|
||||||
|
const char *filename)
|
||||||
|
{
|
||||||
|
PyObject *name = filename ? PyString_FromString(filename) : NULL;
|
||||||
|
PyObject *ret = PyErr_SetExcFromWindowsErrWithFilenameObject(exc,
|
||||||
|
ierr,
|
||||||
|
name);
|
||||||
|
Py_XDECREF(name);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef Py_WIN_WIDE_FILENAMES
|
||||||
|
PyObject *PyErr_SetExcFromWindowsErrWithUnicodeFilename(
|
||||||
|
PyObject *exc,
|
||||||
|
int ierr,
|
||||||
|
const Py_UNICODE *filename)
|
||||||
|
{
|
||||||
|
PyObject *name = filename ?
|
||||||
|
PyUnicode_FromUnicode(filename, wcslen(filename)) :
|
||||||
|
NULL;
|
||||||
|
PyObject *ret = PyErr_SetExcFromWindowsErrWithFilenameObject(exc,
|
||||||
|
ierr,
|
||||||
|
name);
|
||||||
|
Py_XDECREF(name);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#endif /* Py_WIN_WIDE_FILENAMES */
|
||||||
|
|
||||||
PyObject *PyErr_SetExcFromWindowsErr(PyObject *exc, int ierr)
|
PyObject *PyErr_SetExcFromWindowsErr(PyObject *exc, int ierr)
|
||||||
{
|
{
|
||||||
return PyErr_SetExcFromWindowsErrWithFilename(exc, ierr, NULL);
|
return PyErr_SetExcFromWindowsErrWithFilename(exc, ierr, NULL);
|
||||||
|
@ -388,9 +440,29 @@ PyObject *PyErr_SetFromWindowsErrWithFilename(
|
||||||
int ierr,
|
int ierr,
|
||||||
const char *filename)
|
const char *filename)
|
||||||
{
|
{
|
||||||
return PyErr_SetExcFromWindowsErrWithFilename(PyExc_WindowsError,
|
PyObject *name = filename ? PyString_FromString(filename) : NULL;
|
||||||
ierr, filename);
|
PyObject *result = PyErr_SetExcFromWindowsErrWithFilenameObject(
|
||||||
|
PyExc_WindowsError,
|
||||||
|
ierr, name);
|
||||||
|
Py_XDECREF(result);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef Py_WIN_WIDE_FILENAMES
|
||||||
|
PyObject *PyErr_SetFromWindowsErrWithUnicodeFilename(
|
||||||
|
int ierr,
|
||||||
|
const Py_UNICODE *filename)
|
||||||
|
{
|
||||||
|
PyObject *name = filename ?
|
||||||
|
PyUnicode_FromUnicode(filename, wcslen(filename)) :
|
||||||
|
NULL;
|
||||||
|
PyObject *result = PyErr_SetExcFromWindowsErrWithFilenameObject(
|
||||||
|
PyExc_WindowsError,
|
||||||
|
ierr, name);
|
||||||
|
Py_XDECREF(result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
#endif /* Py_WIN_WIDE_FILENAMES */
|
||||||
#endif /* MS_WINDOWS */
|
#endif /* MS_WINDOWS */
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
Loading…
Reference in New Issue