Commit 6c6efb95 authored by Victor Stinner's avatar Victor Stinner

Issue #15478: Raising an OSError doesn't decode or encode the filename anymore

Pass the original filename argument to OSError constructor, instead of trying
to encode it to or decode it from the filesystem encoding. This change avoids
an additionnal UnicodeDecodeError on Windows if the filename cannot be decoded
from the filesystem encoding (ANSI code page).
parent dcb2a6b3
...@@ -246,6 +246,12 @@ The following exceptions are the exceptions that are usually raised. ...@@ -246,6 +246,12 @@ The following exceptions are the exceptions that are usually raised.
:exc:`VMSError`, :exc:`socket.error`, :exc:`select.error` and :exc:`VMSError`, :exc:`socket.error`, :exc:`select.error` and
:exc:`mmap.error` have been merged into :exc:`OSError`. :exc:`mmap.error` have been merged into :exc:`OSError`.
.. versionchanged:: 3.4
The :attr:`filename` attribute is now the original file name passed to
the function, instead of the name encoded to or decoded from the
filesystem encoding.
.. exception:: OverflowError .. exception:: OverflowError
......
...@@ -647,6 +647,17 @@ elif sys.platform != 'darwin': ...@@ -647,6 +647,17 @@ elif sys.platform != 'darwin':
# the byte 0xff. Skip some unicode filename tests. # the byte 0xff. Skip some unicode filename tests.
pass pass
# TESTFN_UNDECODABLE is a filename (bytes type) that should *not* be able to be
# decoded from the filesystem encoding (in strict mode). It can be None if we
# cannot generate such filename.
TESTFN_UNDECODABLE = None
for name in (b'abc\xff', b'\xe7w\xf0'):
try:
os.fsdecode(name)
except UnicodeDecodeErorr:
TESTFN_UNDECODABLE = name
break
# Save the initial cwd # Save the initial cwd
SAVEDCWD = os.getcwd() SAVEDCWD = os.getcwd()
......
...@@ -2046,6 +2046,76 @@ class TermsizeTests(unittest.TestCase): ...@@ -2046,6 +2046,76 @@ class TermsizeTests(unittest.TestCase):
self.assertEqual(expected, actual) self.assertEqual(expected, actual)
class OSErrorTests(unittest.TestCase):
def setUp(self):
class Str(str):
pass
self.filenames = []
if support.TESTFN_UNENCODABLE is not None:
decoded = support.TESTFN_UNENCODABLE
else:
decoded = support.TESTFN
self.filenames.append(decoded)
self.filenames.append(Str(decoded))
if support.TESTFN_UNDECODABLE is not None:
encoded = support.TESTFN_UNDECODABLE
else:
encoded = os.fsencode(support.TESTFN)
self.filenames.append(encoded)
self.filenames.append(memoryview(encoded))
def test_oserror_filename(self):
funcs = [
(os.chdir,),
(os.chmod, 0o777),
(os.chown, 0, 0),
(os.lchown, 0, 0),
(os.listdir,),
(os.lstat,),
(os.open, os.O_RDONLY),
(os.rename, "dst"),
(os.replace, "dst"),
(os.rmdir,),
(os.stat,),
(os.truncate, 0),
(os.unlink,),
]
if sys.platform == "win32":
funcs.extend((
(os._getfullpathname,),
(os._isdir,),
))
if hasattr(os, "chflags"):
funcs.extend((
(os.chflags, 0),
(os.lchflags, 0),
))
if hasattr(os, "chroot"):
funcs.append((os.chroot,))
if hasattr(os, "link"):
funcs.append((os.link, "dst"))
if hasattr(os, "listxattr"):
funcs.extend((
(os.listxattr,),
(os.getxattr, "user.test"),
(os.setxattr, "user.test", b'user'),
(os.removexattr, "user.test"),
))
if hasattr(os, "lchmod"):
funcs.append((os.lchmod, 0o777))
if hasattr(os, "readlink"):
funcs.append((os.readlink,))
for func, *func_args in funcs:
for name in self.filenames:
try:
func(name, *func_args)
except FileNotFoundError as err:
self.assertIs(err.filename, name)
else:
self.fail("No exception thrown by {}".format(func))
@support.reap_threads @support.reap_threads
def test_main(): def test_main():
support.run_unittest( support.run_unittest(
...@@ -2074,6 +2144,7 @@ def test_main(): ...@@ -2074,6 +2144,7 @@ def test_main():
ExtendedAttributeTests, ExtendedAttributeTests,
Win32DeprecatedBytesAPI, Win32DeprecatedBytesAPI,
TermsizeTests, TermsizeTests,
OSErrorTests,
) )
if __name__ == "__main__": if __name__ == "__main__":
......
...@@ -391,12 +391,7 @@ fileio_init(PyObject *oself, PyObject *args, PyObject *kwds) ...@@ -391,12 +391,7 @@ fileio_init(PyObject *oself, PyObject *args, PyObject *kwds)
fd_is_own = 1; fd_is_own = 1;
if (self->fd < 0) { if (self->fd < 0) {
#ifdef MS_WINDOWS PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, nameobj);
if (widename != NULL)
PyErr_SetFromErrnoWithFilenameObject(PyExc_IOError, nameobj);
else
#endif
PyErr_SetFromErrnoWithFilename(PyExc_IOError, name);
goto error; goto error;
} }
} }
......
...@@ -514,8 +514,8 @@ dir_fd_converter(PyObject *o, void *p) { ...@@ -514,8 +514,8 @@ dir_fd_converter(PyObject *o, void *p) {
* path_cleanup(). However it is safe to do so.) * path_cleanup(). However it is safe to do so.)
*/ */
typedef struct { typedef struct {
char *function_name; const char *function_name;
char *argument_name; const char *argument_name;
int nullable; int nullable;
int allow_fd; int allow_fd;
wchar_t *wide; wchar_t *wide;
...@@ -1017,25 +1017,6 @@ posix_error(void) ...@@ -1017,25 +1017,6 @@ posix_error(void)
{ {
return PyErr_SetFromErrno(PyExc_OSError); return PyErr_SetFromErrno(PyExc_OSError);
} }
static PyObject *
posix_error_with_filename(char* name)
{
return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
}
static PyObject *
posix_error_with_allocated_filename(PyObject* name)
{
PyObject *name_str, *rc;
name_str = PyUnicode_DecodeFSDefaultAndSize(PyBytes_AsString(name),
PyBytes_GET_SIZE(name));
Py_DECREF(name);
rc = PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError,
name_str);
Py_XDECREF(name_str);
return rc;
}
#ifdef MS_WINDOWS #ifdef MS_WINDOWS
static PyObject * static PyObject *
...@@ -1080,29 +1061,14 @@ win32_error_object(char* function, PyObject* filename) ...@@ -1080,29 +1061,14 @@ win32_error_object(char* function, PyObject* filename)
#endif /* MS_WINDOWS */ #endif /* MS_WINDOWS */
/*
* Some functions return Win32 errors, others only ever use posix_error
* (this is for backwards compatibility with exceptions)
*/
static PyObject *
path_posix_error(char *function_name, path_t *path)
{
if (path->narrow)
return posix_error_with_filename(path->narrow);
return posix_error();
}
static PyObject * static PyObject *
path_error(char *function_name, path_t *path) path_error(path_t *path)
{ {
#ifdef MS_WINDOWS #ifdef MS_WINDOWS
if (path->narrow) return PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError,
return win32_error(function_name, path->narrow); 0, path->object);
if (path->wide)
return win32_error_unicode(function_name, path->wide);
return win32_error(function_name, NULL);
#else #else
return path_posix_error(function_name, path); return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
#endif #endif
} }
...@@ -1128,21 +1094,25 @@ posix_fildes(PyObject *fdobj, int (*func)(int)) ...@@ -1128,21 +1094,25 @@ posix_fildes(PyObject *fdobj, int (*func)(int))
} }
static PyObject * static PyObject *
posix_1str(PyObject *args, char *format, int (*func)(const char*)) posix_1str(const char *func_name, PyObject *args, char *format,
int (*func)(const char*))
{ {
PyObject *opath1 = NULL; path_t path;
char *path1;
int res; int res;
memset(&path, 0, sizeof(path));
path.function_name = func_name;
if (!PyArg_ParseTuple(args, format, if (!PyArg_ParseTuple(args, format,
PyUnicode_FSConverter, &opath1)) path_converter, &path))
return NULL; return NULL;
path1 = PyBytes_AsString(opath1);
Py_BEGIN_ALLOW_THREADS Py_BEGIN_ALLOW_THREADS
res = (*func)(path1); res = (*func)(path.narrow);
Py_END_ALLOW_THREADS Py_END_ALLOW_THREADS
if (res < 0) if (res < 0) {
return posix_error_with_allocated_filename(opath1); path_error(&path);
Py_DECREF(opath1); path_cleanup(&path);
return NULL;
}
path_cleanup(&path);
Py_INCREF(Py_None); Py_INCREF(Py_None);
return Py_None; return Py_None;
} }
...@@ -2158,8 +2128,9 @@ posix_do_stat(char *function_name, path_t *path, ...@@ -2158,8 +2128,9 @@ posix_do_stat(char *function_name, path_t *path,
result = STAT(path->narrow, &st); result = STAT(path->narrow, &st);
Py_END_ALLOW_THREADS Py_END_ALLOW_THREADS
if (result != 0) if (result != 0) {
return path_error("stat", path); return path_error(path);
}
return _pystat_fromstructstat(&st); return _pystat_fromstructstat(&st);
} }
...@@ -2190,6 +2161,7 @@ posix_stat(PyObject *self, PyObject *args, PyObject *kwargs) ...@@ -2190,6 +2161,7 @@ posix_stat(PyObject *self, PyObject *args, PyObject *kwargs)
PyObject *return_value; PyObject *return_value;
memset(&path, 0, sizeof(path)); memset(&path, 0, sizeof(path));
path.function_name = "stat";
path.allow_fd = 1; path.allow_fd = 1;
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&p:stat", keywords, if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&p:stat", keywords,
path_converter, &path, path_converter, &path,
...@@ -2220,6 +2192,7 @@ posix_lstat(PyObject *self, PyObject *args, PyObject *kwargs) ...@@ -2220,6 +2192,7 @@ posix_lstat(PyObject *self, PyObject *args, PyObject *kwargs)
PyObject *return_value; PyObject *return_value;
memset(&path, 0, sizeof(path)); memset(&path, 0, sizeof(path));
path.function_name = "lstat";
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:lstat", keywords, if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:lstat", keywords,
path_converter, &path, path_converter, &path,
#ifdef HAVE_FSTATAT #ifdef HAVE_FSTATAT
...@@ -2428,6 +2401,7 @@ posix_chdir(PyObject *self, PyObject *args, PyObject *kwargs) ...@@ -2428,6 +2401,7 @@ posix_chdir(PyObject *self, PyObject *args, PyObject *kwargs)
static char *keywords[] = {"path", NULL}; static char *keywords[] = {"path", NULL};
memset(&path, 0, sizeof(path)); memset(&path, 0, sizeof(path));
path.function_name = "chdir";
#ifdef HAVE_FCHDIR #ifdef HAVE_FCHDIR
path.allow_fd = 1; path.allow_fd = 1;
#endif #endif
...@@ -2454,7 +2428,7 @@ posix_chdir(PyObject *self, PyObject *args, PyObject *kwargs) ...@@ -2454,7 +2428,7 @@ posix_chdir(PyObject *self, PyObject *args, PyObject *kwargs)
Py_END_ALLOW_THREADS Py_END_ALLOW_THREADS
if (result) { if (result) {
return_value = path_error("chdir", &path); return_value = path_error(&path);
goto exit; goto exit;
} }
...@@ -2518,6 +2492,7 @@ posix_chmod(PyObject *self, PyObject *args, PyObject *kwargs) ...@@ -2518,6 +2492,7 @@ posix_chmod(PyObject *self, PyObject *args, PyObject *kwargs)
#endif #endif
memset(&path, 0, sizeof(path)); memset(&path, 0, sizeof(path));
path.function_name = "chmod";
#ifdef HAVE_FCHMOD #ifdef HAVE_FCHMOD
path.allow_fd = 1; path.allow_fd = 1;
#endif #endif
...@@ -2612,7 +2587,7 @@ posix_chmod(PyObject *self, PyObject *args, PyObject *kwargs) ...@@ -2612,7 +2587,7 @@ posix_chmod(PyObject *self, PyObject *args, PyObject *kwargs)
} }
else else
#endif #endif
return_value = path_error("chmod", &path); return_value = path_error(&path);
goto exit; goto exit;
} }
#endif #endif
...@@ -2656,20 +2631,23 @@ Equivalent to chmod(path, mode, follow_symlinks=False)."); ...@@ -2656,20 +2631,23 @@ Equivalent to chmod(path, mode, follow_symlinks=False).");
static PyObject * static PyObject *
posix_lchmod(PyObject *self, PyObject *args) posix_lchmod(PyObject *self, PyObject *args)
{ {
PyObject *opath; path_t path;
char *path;
int i; int i;
int res; int res;
if (!PyArg_ParseTuple(args, "O&i:lchmod", PyUnicode_FSConverter, memset(&path, 0, sizeof(path));
&opath, &i)) path.function_name = "lchmod";
if (!PyArg_ParseTuple(args, "O&i:lchmod",
path_converter, &path, &i))
return NULL; return NULL;
path = PyBytes_AsString(opath);
Py_BEGIN_ALLOW_THREADS Py_BEGIN_ALLOW_THREADS
res = lchmod(path, i); res = lchmod(path.narrow, i);
Py_END_ALLOW_THREADS Py_END_ALLOW_THREADS
if (res < 0) if (res < 0) {
return posix_error_with_allocated_filename(opath); path_error(&path);
Py_DECREF(opath); path_cleanup(&path);
return NULL;
}
path_cleanup(&path);
Py_RETURN_NONE; Py_RETURN_NONE;
} }
#endif /* HAVE_LCHMOD */ #endif /* HAVE_LCHMOD */
...@@ -2697,6 +2675,7 @@ posix_chflags(PyObject *self, PyObject *args, PyObject *kwargs) ...@@ -2697,6 +2675,7 @@ posix_chflags(PyObject *self, PyObject *args, PyObject *kwargs)
static char *keywords[] = {"path", "flags", "follow_symlinks", NULL}; static char *keywords[] = {"path", "flags", "follow_symlinks", NULL};
memset(&path, 0, sizeof(path)); memset(&path, 0, sizeof(path));
path.function_name = "chflags";
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&k|$i:chflags", keywords, if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&k|$i:chflags", keywords,
path_converter, &path, path_converter, &path,
&flags, &follow_symlinks)) &flags, &follow_symlinks))
...@@ -2717,7 +2696,7 @@ posix_chflags(PyObject *self, PyObject *args, PyObject *kwargs) ...@@ -2717,7 +2696,7 @@ posix_chflags(PyObject *self, PyObject *args, PyObject *kwargs)
Py_END_ALLOW_THREADS Py_END_ALLOW_THREADS
if (result) { if (result) {
return_value = path_posix_error("chflags", &path); return_value = path_error(&path);
goto exit; goto exit;
} }
...@@ -2740,22 +2719,25 @@ Equivalent to chflags(path, flags, follow_symlinks=False)."); ...@@ -2740,22 +2719,25 @@ Equivalent to chflags(path, flags, follow_symlinks=False).");
static PyObject * static PyObject *
posix_lchflags(PyObject *self, PyObject *args) posix_lchflags(PyObject *self, PyObject *args)
{ {
PyObject *opath; path_t path;
char *path; char *path;
unsigned long flags; unsigned long flags;
int res; int res;
memset(&path, 0, sizeof(path));
path.function_name = "lchflags";
if (!PyArg_ParseTuple(args, "O&k:lchflags", if (!PyArg_ParseTuple(args, "O&k:lchflags",
PyUnicode_FSConverter, &opath, &flags)) path_converter, &path, &flags))
return NULL; return NULL;
path = PyBytes_AsString(opath);
Py_BEGIN_ALLOW_THREADS Py_BEGIN_ALLOW_THREADS
res = lchflags(path, flags); res = lchflags(path.narrow, flags);
Py_END_ALLOW_THREADS Py_END_ALLOW_THREADS
if (res < 0) if (res < 0) {
return posix_error_with_allocated_filename(opath); path_error(&path);
Py_DECREF(opath); path_cleanup(&path);
Py_INCREF(Py_None); return NULL;
return Py_None; }
path_cleanup(&path);
Py_RETURN_NONE;
} }
#endif /* HAVE_LCHFLAGS */ #endif /* HAVE_LCHFLAGS */
...@@ -2767,7 +2749,7 @@ Change root directory to path."); ...@@ -2767,7 +2749,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, "O&:chroot", chroot); return posix_1str("chroot", args, "O&:chroot", chroot);
} }
#endif #endif
...@@ -2850,6 +2832,7 @@ posix_chown(PyObject *self, PyObject *args, PyObject *kwargs) ...@@ -2850,6 +2832,7 @@ posix_chown(PyObject *self, PyObject *args, PyObject *kwargs)
"follow_symlinks", NULL}; "follow_symlinks", NULL};
memset(&path, 0, sizeof(path)); memset(&path, 0, sizeof(path));
path.function_name = "chown";
#ifdef HAVE_FCHOWN #ifdef HAVE_FCHOWN
path.allow_fd = 1; path.allow_fd = 1;
#endif #endif
...@@ -2908,7 +2891,7 @@ posix_chown(PyObject *self, PyObject *args, PyObject *kwargs) ...@@ -2908,7 +2891,7 @@ posix_chown(PyObject *self, PyObject *args, PyObject *kwargs)
Py_END_ALLOW_THREADS Py_END_ALLOW_THREADS
if (result) { if (result) {
return_value = path_posix_error("chown", &path); return_value = path_error(&path);
goto exit; goto exit;
} }
...@@ -2954,21 +2937,24 @@ Equivalent to os.chown(path, uid, gid, follow_symlinks=False)."); ...@@ -2954,21 +2937,24 @@ Equivalent to os.chown(path, uid, gid, follow_symlinks=False).");
static PyObject * static PyObject *
posix_lchown(PyObject *self, PyObject *args) posix_lchown(PyObject *self, PyObject *args)
{ {
PyObject *opath; path_t path;
char *path;
long uid, gid; long uid, gid;
int res; int res;
memset(&path, 0, sizeof(path));
path.function_name = "lchown";
if (!PyArg_ParseTuple(args, "O&ll:lchown", if (!PyArg_ParseTuple(args, "O&ll:lchown",
PyUnicode_FSConverter, &opath, path_converter, &path,
&uid, &gid)) &uid, &gid))
return NULL; return NULL;
path = PyBytes_AsString(opath);
Py_BEGIN_ALLOW_THREADS Py_BEGIN_ALLOW_THREADS
res = lchown(path, (uid_t) uid, (gid_t) gid); res = lchown(path.narrow, (uid_t) uid, (gid_t) gid);
Py_END_ALLOW_THREADS Py_END_ALLOW_THREADS
if (res < 0) if (res < 0) {
return posix_error_with_allocated_filename(opath); path_error(&path);
Py_DECREF(opath); path_cleanup(&path);
return NULL;
}
path_cleanup(&path);
Py_INCREF(Py_None); Py_INCREF(Py_None);
return Py_None; return Py_None;
} }
...@@ -3084,6 +3070,8 @@ posix_link(PyObject *self, PyObject *args, PyObject *kwargs) ...@@ -3084,6 +3070,8 @@ posix_link(PyObject *self, PyObject *args, PyObject *kwargs)
memset(&src, 0, sizeof(src)); memset(&src, 0, sizeof(src));
memset(&dst, 0, sizeof(dst)); memset(&dst, 0, sizeof(dst));
src.function_name = "link";
dst.function_name = "link";
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|O&O&p:link", keywords, if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|O&O&p:link", keywords,
path_converter, &src, path_converter, &src,
path_converter, &dst, path_converter, &dst,
...@@ -3132,7 +3120,7 @@ posix_link(PyObject *self, PyObject *args, PyObject *kwargs) ...@@ -3132,7 +3120,7 @@ posix_link(PyObject *self, PyObject *args, PyObject *kwargs)
Py_END_ALLOW_THREADS Py_END_ALLOW_THREADS
if (result) { if (result) {
return_value = path_error("link", &dst); return_value = path_error(&src);
goto exit; goto exit;
} }
#endif #endif
...@@ -3189,6 +3177,7 @@ posix_listdir(PyObject *self, PyObject *args, PyObject *kwargs) ...@@ -3189,6 +3177,7 @@ posix_listdir(PyObject *self, PyObject *args, PyObject *kwargs)
#endif #endif
memset(&path, 0, sizeof(path)); memset(&path, 0, sizeof(path));
path.function_name = "listdir";
path.nullable = 1; path.nullable = 1;
#ifdef HAVE_FDOPENDIR #ifdef HAVE_FDOPENDIR
path.allow_fd = 1; path.allow_fd = 1;
...@@ -3383,7 +3372,7 @@ exit: ...@@ -3383,7 +3372,7 @@ exit:
} }
if (dirp == NULL) { if (dirp == NULL) {
list = path_error("listdir", &path); list = path_error(&path);
goto exit; goto exit;
} }
if ((list = PyList_New(0)) == NULL) { if ((list = PyList_New(0)) == NULL) {
...@@ -3399,7 +3388,7 @@ exit: ...@@ -3399,7 +3388,7 @@ exit:
break; break;
} else { } else {
Py_DECREF(list); Py_DECREF(list);
list = path_error("listdir", &path); list = path_error(&path);
goto exit; goto exit;
} }
} }
...@@ -3650,6 +3639,7 @@ posix_mkdir(PyObject *self, PyObject *args, PyObject *kwargs) ...@@ -3650,6 +3639,7 @@ posix_mkdir(PyObject *self, PyObject *args, PyObject *kwargs)
int result; int result;
memset(&path, 0, sizeof(path)); memset(&path, 0, sizeof(path));
path.function_name = "mkdir";
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|i$O&:mkdir", keywords, if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|i$O&:mkdir", keywords,
path_converter, &path, &mode, path_converter, &path, &mode,
#ifdef HAVE_MKDIRAT #ifdef HAVE_MKDIRAT
...@@ -3686,7 +3676,7 @@ posix_mkdir(PyObject *self, PyObject *args, PyObject *kwargs) ...@@ -3686,7 +3676,7 @@ posix_mkdir(PyObject *self, PyObject *args, PyObject *kwargs)
#endif #endif
Py_END_ALLOW_THREADS Py_END_ALLOW_THREADS
if (result < 0) { if (result < 0) {
return_value = path_error("mkdir", &path); return_value = path_error(&path);
goto exit; goto exit;
} }
#endif #endif
...@@ -3804,6 +3794,8 @@ internal_rename(PyObject *args, PyObject *kwargs, int is_replace) ...@@ -3804,6 +3794,8 @@ internal_rename(PyObject *args, PyObject *kwargs, int is_replace)
memset(&src, 0, sizeof(src)); memset(&src, 0, sizeof(src));
memset(&dst, 0, sizeof(dst)); memset(&dst, 0, sizeof(dst));
src.function_name = function_name;
dst.function_name = function_name;
strcpy(format, "O&O&|$O&O&:"); strcpy(format, "O&O&|$O&O&:");
strcat(format, function_name); strcat(format, function_name);
if (!PyArg_ParseTupleAndKeywords(args, kwargs, format, keywords, if (!PyArg_ParseTupleAndKeywords(args, kwargs, format, keywords,
...@@ -3852,7 +3844,7 @@ internal_rename(PyObject *args, PyObject *kwargs, int is_replace) ...@@ -3852,7 +3844,7 @@ internal_rename(PyObject *args, PyObject *kwargs, int is_replace)
Py_END_ALLOW_THREADS Py_END_ALLOW_THREADS
if (result) { if (result) {
return_value = path_error(function_name, &dst); return_value = path_error(&src);
goto exit; goto exit;
} }
#endif #endif
...@@ -3916,6 +3908,7 @@ posix_rmdir(PyObject *self, PyObject *args, PyObject *kwargs) ...@@ -3916,6 +3908,7 @@ posix_rmdir(PyObject *self, PyObject *args, PyObject *kwargs)
PyObject *return_value = NULL; PyObject *return_value = NULL;
memset(&path, 0, sizeof(path)); memset(&path, 0, sizeof(path));
path.function_name = "rmdir";
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:rmdir", keywords, if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:rmdir", keywords,
path_converter, &path, path_converter, &path,
#ifdef HAVE_UNLINKAT #ifdef HAVE_UNLINKAT
...@@ -3944,7 +3937,7 @@ posix_rmdir(PyObject *self, PyObject *args, PyObject *kwargs) ...@@ -3944,7 +3937,7 @@ posix_rmdir(PyObject *self, PyObject *args, PyObject *kwargs)
Py_END_ALLOW_THREADS Py_END_ALLOW_THREADS
if (result) { if (result) {
return_value = path_error("rmdir", &path); return_value = path_error(&path);
goto exit; goto exit;
} }
...@@ -4072,6 +4065,7 @@ posix_unlink(PyObject *self, PyObject *args, PyObject *kwargs) ...@@ -4072,6 +4065,7 @@ posix_unlink(PyObject *self, PyObject *args, PyObject *kwargs)
PyObject *return_value = NULL; PyObject *return_value = NULL;
memset(&path, 0, sizeof(path)); memset(&path, 0, sizeof(path));
path.function_name = "unlink";
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:unlink", keywords, if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:unlink", keywords,
path_converter, &path, path_converter, &path,
#ifdef HAVE_UNLINKAT #ifdef HAVE_UNLINKAT
...@@ -4100,7 +4094,7 @@ posix_unlink(PyObject *self, PyObject *args, PyObject *kwargs) ...@@ -4100,7 +4094,7 @@ posix_unlink(PyObject *self, PyObject *args, PyObject *kwargs)
Py_END_ALLOW_THREADS Py_END_ALLOW_THREADS
if (result) { if (result) {
return_value = path_error("unlink", &path); return_value = path_error(&path);
goto exit; goto exit;
} }
...@@ -4787,6 +4781,7 @@ posix_execve(PyObject *self, PyObject *args, PyObject *kwargs) ...@@ -4787,6 +4781,7 @@ posix_execve(PyObject *self, PyObject *args, PyObject *kwargs)
like posix.environ. */ like posix.environ. */
memset(&path, 0, sizeof(path)); memset(&path, 0, sizeof(path));
path.function_name = "execve";
#ifdef HAVE_FEXECVE #ifdef HAVE_FEXECVE
path.allow_fd = 1; path.allow_fd = 1;
#endif #endif
...@@ -4826,7 +4821,7 @@ posix_execve(PyObject *self, PyObject *args, PyObject *kwargs) ...@@ -4826,7 +4821,7 @@ posix_execve(PyObject *self, PyObject *args, PyObject *kwargs)
/* If we get here it's definitely an error */ /* If we get here it's definitely an error */
path_posix_error("execve", &path); path_error(&path);
while (--envc >= 0) while (--envc >= 0)
PyMem_DEL(envlist[envc]); PyMem_DEL(envlist[envc]);
...@@ -6602,6 +6597,7 @@ posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs) ...@@ -6602,6 +6597,7 @@ posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
static char *keywords[] = {"path", "dir_fd", NULL}; static char *keywords[] = {"path", "dir_fd", NULL};
memset(&path, 0, sizeof(path)); memset(&path, 0, sizeof(path));
path.function_name = "readlink";
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:readlink", keywords, if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:readlink", keywords,
path_converter, &path, path_converter, &path,
#ifdef HAVE_READLINKAT #ifdef HAVE_READLINKAT
...@@ -6622,7 +6618,7 @@ posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs) ...@@ -6622,7 +6618,7 @@ posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Py_END_ALLOW_THREADS Py_END_ALLOW_THREADS
if (length < 0) { if (length < 0) {
return_value = path_posix_error("readlink", &path); return_value = path_error(&path);
goto exit; goto exit;
} }
...@@ -6692,8 +6688,10 @@ posix_symlink(PyObject *self, PyObject *args, PyObject *kwargs) ...@@ -6692,8 +6688,10 @@ posix_symlink(PyObject *self, PyObject *args, PyObject *kwargs)
#endif #endif
memset(&src, 0, sizeof(src)); memset(&src, 0, sizeof(src));
src.function_name = "symlink";
src.argument_name = "src"; src.argument_name = "src";
memset(&dst, 0, sizeof(dst)); memset(&dst, 0, sizeof(dst));
dst.function_name = "symlink";
dst.argument_name = "dst"; dst.argument_name = "dst";
#ifdef MS_WINDOWS #ifdef MS_WINDOWS
...@@ -6755,7 +6753,7 @@ posix_symlink(PyObject *self, PyObject *args, PyObject *kwargs) ...@@ -6755,7 +6753,7 @@ posix_symlink(PyObject *self, PyObject *args, PyObject *kwargs)
Py_END_ALLOW_THREADS Py_END_ALLOW_THREADS
if (result) { if (result) {
return_value = path_error("symlink", &dst); return_value = path_error(&dst);
goto exit; goto exit;
} }
#endif #endif
...@@ -7080,6 +7078,7 @@ posix_open(PyObject *self, PyObject *args, PyObject *kwargs) ...@@ -7080,6 +7078,7 @@ posix_open(PyObject *self, PyObject *args, PyObject *kwargs)
static char *keywords[] = {"path", "flags", "mode", "dir_fd", NULL}; static char *keywords[] = {"path", "flags", "mode", "dir_fd", NULL};
memset(&path, 0, sizeof(path)); memset(&path, 0, sizeof(path));
path.function_name = "open";
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|i$O&:open", keywords, if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|i$O&:open", keywords,
path_converter, &path, path_converter, &path,
&flags, &mode, &flags, &mode,
...@@ -7112,7 +7111,7 @@ posix_open(PyObject *self, PyObject *args, PyObject *kwargs) ...@@ -7112,7 +7111,7 @@ posix_open(PyObject *self, PyObject *args, PyObject *kwargs)
return_value = posix_error(); return_value = posix_error();
else else
#endif #endif
return_value = path_error("open", &path); return_value = path_error(&path);
goto exit; goto exit;
} }
...@@ -7999,6 +7998,7 @@ posix_truncate(PyObject *self, PyObject *args, PyObject *kwargs) ...@@ -7999,6 +7998,7 @@ posix_truncate(PyObject *self, PyObject *args, PyObject *kwargs)
static char *keywords[] = {"path", "length", NULL}; static char *keywords[] = {"path", "length", NULL};
memset(&path, 0, sizeof(path)); memset(&path, 0, sizeof(path));
path.function_name = "truncate";
#ifdef HAVE_FTRUNCATE #ifdef HAVE_FTRUNCATE
path.allow_fd = 1; path.allow_fd = 1;
#endif #endif
...@@ -8016,7 +8016,7 @@ posix_truncate(PyObject *self, PyObject *args, PyObject *kwargs) ...@@ -8016,7 +8016,7 @@ posix_truncate(PyObject *self, PyObject *args, PyObject *kwargs)
res = truncate(path.narrow, length); res = truncate(path.narrow, length);
Py_END_ALLOW_THREADS Py_END_ALLOW_THREADS
if (res < 0) if (res < 0)
result = path_posix_error("truncate", &path); result = path_error(&path);
else { else {
Py_INCREF(Py_None); Py_INCREF(Py_None);
result = Py_None; result = Py_None;
...@@ -8488,6 +8488,7 @@ posix_statvfs(PyObject *self, PyObject *args, PyObject *kwargs) ...@@ -8488,6 +8488,7 @@ posix_statvfs(PyObject *self, PyObject *args, PyObject *kwargs)
struct statvfs st; struct statvfs st;
memset(&path, 0, sizeof(path)); memset(&path, 0, sizeof(path));
path.function_name = "statvfs";
#ifdef HAVE_FSTATVFS #ifdef HAVE_FSTATVFS
path.allow_fd = 1; path.allow_fd = 1;
#endif #endif
...@@ -8514,7 +8515,7 @@ posix_statvfs(PyObject *self, PyObject *args, PyObject *kwargs) ...@@ -8514,7 +8515,7 @@ posix_statvfs(PyObject *self, PyObject *args, PyObject *kwargs)
Py_END_ALLOW_THREADS Py_END_ALLOW_THREADS
if (result) { if (result) {
return_value = path_posix_error("statvfs", &path); return_value = path_error(&path);
goto exit; goto exit;
} }
...@@ -8751,6 +8752,7 @@ posix_pathconf(PyObject *self, PyObject *args, PyObject *kwargs) ...@@ -8751,6 +8752,7 @@ posix_pathconf(PyObject *self, PyObject *args, PyObject *kwargs)
static char *keywords[] = {"path", "name", NULL}; static char *keywords[] = {"path", "name", NULL};
memset(&path, 0, sizeof(path)); memset(&path, 0, sizeof(path));
path.function_name = "pathconf";
#ifdef HAVE_FPATHCONF #ifdef HAVE_FPATHCONF
path.allow_fd = 1; path.allow_fd = 1;
#endif #endif
...@@ -8771,7 +8773,7 @@ posix_pathconf(PyObject *self, PyObject *args, PyObject *kwargs) ...@@ -8771,7 +8773,7 @@ posix_pathconf(PyObject *self, PyObject *args, PyObject *kwargs)
/* could be a path or name problem */ /* could be a path or name problem */
posix_error(); posix_error();
else else
result = path_posix_error("pathconf", &path); result = path_error(&path);
} }
else else
result = PyLong_FromLong(limit); result = PyLong_FromLong(limit);
...@@ -9831,6 +9833,8 @@ posix_getxattr(PyObject *self, PyObject *args, PyObject *kwargs) ...@@ -9831,6 +9833,8 @@ posix_getxattr(PyObject *self, PyObject *args, PyObject *kwargs)
memset(&path, 0, sizeof(path)); memset(&path, 0, sizeof(path));
memset(&attribute, 0, sizeof(attribute)); memset(&attribute, 0, sizeof(attribute));
path.function_name = "getxattr";
attribute.function_name = "getxattr";
path.allow_fd = 1; path.allow_fd = 1;
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$p:getxattr", keywords, if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$p:getxattr", keywords,
path_converter, &path, path_converter, &path,
...@@ -9847,7 +9851,7 @@ posix_getxattr(PyObject *self, PyObject *args, PyObject *kwargs) ...@@ -9847,7 +9851,7 @@ posix_getxattr(PyObject *self, PyObject *args, PyObject *kwargs)
static Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0}; static Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
Py_ssize_t buffer_size = buffer_sizes[i]; Py_ssize_t buffer_size = buffer_sizes[i];
if (!buffer_size) { if (!buffer_size) {
path_error("getxattr", &path); path_error(&path);
goto exit; goto exit;
} }
buffer = PyBytes_FromStringAndSize(NULL, buffer_size); buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
...@@ -9869,7 +9873,7 @@ posix_getxattr(PyObject *self, PyObject *args, PyObject *kwargs) ...@@ -9869,7 +9873,7 @@ posix_getxattr(PyObject *self, PyObject *args, PyObject *kwargs)
buffer = NULL; buffer = NULL;
if (errno == ERANGE) if (errno == ERANGE)
continue; continue;
path_error("getxattr", &path); path_error(&path);
goto exit; goto exit;
} }
...@@ -9908,6 +9912,7 @@ posix_setxattr(PyObject *self, PyObject *args, PyObject *kwargs) ...@@ -9908,6 +9912,7 @@ posix_setxattr(PyObject *self, PyObject *args, PyObject *kwargs)
"flags", "follow_symlinks", NULL}; "flags", "follow_symlinks", NULL};
memset(&path, 0, sizeof(path)); memset(&path, 0, sizeof(path));
path.function_name = "setxattr";
path.allow_fd = 1; path.allow_fd = 1;
memset(&attribute, 0, sizeof(attribute)); memset(&attribute, 0, sizeof(attribute));
memset(&value, 0, sizeof(value)); memset(&value, 0, sizeof(value));
...@@ -9935,7 +9940,7 @@ posix_setxattr(PyObject *self, PyObject *args, PyObject *kwargs) ...@@ -9935,7 +9940,7 @@ posix_setxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Py_END_ALLOW_THREADS; Py_END_ALLOW_THREADS;
if (result) { if (result) {
return_value = path_error("setxattr", &path); return_value = path_error(&path);
goto exit; goto exit;
} }
...@@ -9969,7 +9974,9 @@ posix_removexattr(PyObject *self, PyObject *args, PyObject *kwargs) ...@@ -9969,7 +9974,9 @@ posix_removexattr(PyObject *self, PyObject *args, PyObject *kwargs)
static char *keywords[] = {"path", "attribute", "follow_symlinks", NULL}; static char *keywords[] = {"path", "attribute", "follow_symlinks", NULL};
memset(&path, 0, sizeof(path)); memset(&path, 0, sizeof(path));
path.function_name = "removexattr";
memset(&attribute, 0, sizeof(attribute)); memset(&attribute, 0, sizeof(attribute));
attribute.function_name = "removexattr";
path.allow_fd = 1; path.allow_fd = 1;
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$p:removexattr", if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$p:removexattr",
keywords, keywords,
...@@ -9991,7 +9998,7 @@ posix_removexattr(PyObject *self, PyObject *args, PyObject *kwargs) ...@@ -9991,7 +9998,7 @@ posix_removexattr(PyObject *self, PyObject *args, PyObject *kwargs)
Py_END_ALLOW_THREADS; Py_END_ALLOW_THREADS;
if (result) { if (result) {
return_value = path_error("removexattr", &path); return_value = path_error(&path);
goto exit; goto exit;
} }
...@@ -10027,6 +10034,7 @@ posix_listxattr(PyObject *self, PyObject *args, PyObject *kwargs) ...@@ -10027,6 +10034,7 @@ posix_listxattr(PyObject *self, PyObject *args, PyObject *kwargs)
static char *keywords[] = {"path", "follow_symlinks", NULL}; static char *keywords[] = {"path", "follow_symlinks", NULL};
memset(&path, 0, sizeof(path)); memset(&path, 0, sizeof(path));
path.function_name = "listxattr";
path.allow_fd = 1; path.allow_fd = 1;
path.fd = -1; path.fd = -1;
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&$p:listxattr", keywords, if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&$p:listxattr", keywords,
...@@ -10045,7 +10053,7 @@ posix_listxattr(PyObject *self, PyObject *args, PyObject *kwargs) ...@@ -10045,7 +10053,7 @@ posix_listxattr(PyObject *self, PyObject *args, PyObject *kwargs)
Py_ssize_t buffer_size = buffer_sizes[i]; Py_ssize_t buffer_size = buffer_sizes[i];
if (!buffer_size) { if (!buffer_size) {
/* ERANGE */ /* ERANGE */
path_error("listxattr", &path); path_error(&path);
break; break;
} }
buffer = PyMem_MALLOC(buffer_size); buffer = PyMem_MALLOC(buffer_size);
...@@ -10066,7 +10074,7 @@ posix_listxattr(PyObject *self, PyObject *args, PyObject *kwargs) ...@@ -10066,7 +10074,7 @@ posix_listxattr(PyObject *self, PyObject *args, PyObject *kwargs)
if (length < 0) { if (length < 0) {
if (errno == ERANGE) if (errno == ERANGE)
continue; continue;
path_error("listxattr", &path); path_error(&path);
break; break;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment