diff options
author | Larry Hastings <larry@hastings.org> | 2014-02-10 06:05:19 (GMT) |
---|---|---|
committer | Larry Hastings <larry@hastings.org> | 2014-02-10 06:05:19 (GMT) |
commit | b082731fbb413a7ff2412a447698fdd65015fd24 (patch) | |
tree | 6cb37b4aacee0af28c057079af5545cf92dd1537 /Python/errors.c | |
parent | dc62b7e261ab88b4ab967ac2ae307eddbfa0ae09 (diff) | |
download | cpython-b082731fbb413a7ff2412a447698fdd65015fd24.zip cpython-b082731fbb413a7ff2412a447698fdd65015fd24.tar.gz cpython-b082731fbb413a7ff2412a447698fdd65015fd24.tar.bz2 |
Issue #20517: Functions in the os module that accept two filenames
now register both filenames in the exception on failure.
This required adding new C API functions allowing OSError exceptions
to reference two filenames instead of one.
Diffstat (limited to 'Python/errors.c')
-rw-r--r-- | Python/errors.c | 169 |
1 files changed, 147 insertions, 22 deletions
diff --git a/Python/errors.c b/Python/errors.c index 90dc729..0057e5e 100644 --- a/Python/errors.c +++ b/Python/errors.c @@ -410,6 +410,12 @@ PyErr_NoMemory(void) PyObject * PyErr_SetFromErrnoWithFilenameObject(PyObject *exc, PyObject *filenameObject) { + return PyErr_SetFromErrnoWithFilenameObjects(exc, filenameObject, NULL); +} + +PyObject * +PyErr_SetFromErrnoWithFilenameObjects(PyObject *exc, PyObject *filenameObject, PyObject *filenameObject2) +{ PyObject *message; PyObject *v, *args; int i = errno; @@ -480,10 +486,15 @@ PyErr_SetFromErrnoWithFilenameObject(PyObject *exc, PyObject *filenameObject) return NULL; } - if (filenameObject != NULL) - args = Py_BuildValue("(iOO)", i, message, filenameObject); - else + if (filenameObject != NULL) { + if (filenameObject2 != NULL) + args = Py_BuildValue("(iOOiO)", i, message, filenameObject, 0, filenameObject2); + else + args = Py_BuildValue("(iOO)", i, message, filenameObject); + } else { + assert(filenameObject2 == NULL); args = Py_BuildValue("(iO)", i, message); + } Py_DECREF(message); if (args != NULL) { @@ -500,16 +511,26 @@ PyErr_SetFromErrnoWithFilenameObject(PyObject *exc, PyObject *filenameObject) return NULL; } - PyObject * PyErr_SetFromErrnoWithFilename(PyObject *exc, const char *filename) { PyObject *name = filename ? PyUnicode_DecodeFSDefault(filename) : NULL; - PyObject *result = PyErr_SetFromErrnoWithFilenameObject(exc, name); + PyObject *result = PyErr_SetFromErrnoWithFilenameObjects(exc, name, NULL); Py_XDECREF(name); return result; } +PyObject * +PyErr_SetFromErrnoWithFilenames(PyObject *exc, const char *filename, const char *filename2) +{ + PyObject *name = filename ? PyUnicode_DecodeFSDefault(filename) : NULL; + PyObject *name2 = filename2 ? PyUnicode_DecodeFSDefault(filename2) : NULL; + PyObject *result = PyErr_SetFromErrnoWithFilenameObjects(exc, name, name2); + Py_XDECREF(name); + Py_XDECREF(name2); + return result; +} + #ifdef MS_WINDOWS PyObject * PyErr_SetFromErrnoWithUnicodeFilename(PyObject *exc, const Py_UNICODE *filename) @@ -517,16 +538,31 @@ PyErr_SetFromErrnoWithUnicodeFilename(PyObject *exc, const Py_UNICODE *filename) PyObject *name = filename ? PyUnicode_FromUnicode(filename, wcslen(filename)) : NULL; - PyObject *result = PyErr_SetFromErrnoWithFilenameObject(exc, name); + PyObject *result = PyErr_SetFromErrnoWithFilenameObjects(exc, name, NULL); Py_XDECREF(name); return result; } + +PyObject * +PyErr_SetFromErrnoWithUnicodeFilenames(PyObject *exc, const Py_UNICODE *filename, const Py_UNICODE *filename2) +{ + PyObject *name = filename ? + PyUnicode_FromUnicode(filename, wcslen(filename)) : + NULL; + PyObject *name2 = filename2 ? + PyUnicode_FromUnicode(filename2, wcslen(filename2)) : + NULL; + PyObject *result = PyErr_SetFromErrnoWithFilenameObjects(exc, name, name2); + Py_XDECREF(name); + Py_XDECREF(name2); + return result; +} #endif /* MS_WINDOWS */ PyObject * PyErr_SetFromErrno(PyObject *exc) { - return PyErr_SetFromErrnoWithFilenameObject(exc, NULL); + return PyErr_SetFromErrnoWithFilenameObjects(exc, NULL, NULL); } #ifdef MS_WINDOWS @@ -536,6 +572,16 @@ PyObject *PyErr_SetExcFromWindowsErrWithFilenameObject( int ierr, PyObject *filenameObject) { + return PyErr_SetExcFromWindowsErrWithFilenameObjects(exc, ierr, + filenameObject, NULL); +} + +PyObject *PyErr_SetExcFromWindowsErrWithFilenameObjects( + PyObject *exc, + int ierr, + PyObject *filenameObject, + PyObject *filenameObject2) +{ int len; WCHAR *s_buf = NULL; /* Free via LocalFree */ PyObject *message; @@ -571,11 +617,15 @@ PyObject *PyErr_SetExcFromWindowsErrWithFilenameObject( return NULL; } - if (filenameObject == NULL) - filenameObject = Py_None; - /* This is the constructor signature for passing a Windows error code. + if (filenameObject == NULL) { + assert(filenameObject2 == NULL); + filenameObject = filenameObject2 = Py_None; + } + else if (filenameObject2 == NULL) + filenameObject2 = Py_None; + /* This is the constructor signature for OSError. The POSIX translation will be figured out by the constructor. */ - args = Py_BuildValue("(iOOi)", 0, message, filenameObject, err); + args = Py_BuildValue("(iOOiO)", 0, message, filenameObject, err, filenameObject2); Py_DECREF(message); if (args != NULL) { @@ -596,13 +646,31 @@ PyObject *PyErr_SetExcFromWindowsErrWithFilename( const char *filename) { PyObject *name = filename ? PyUnicode_DecodeFSDefault(filename) : NULL; - PyObject *ret = PyErr_SetExcFromWindowsErrWithFilenameObject(exc, + PyObject *ret = PyErr_SetExcFromWindowsErrWithFilenameObjects(exc, ierr, - name); + name, + NULL); Py_XDECREF(name); return ret; } +PyObject *PyErr_SetExcFromWindowsErrWithFilenames( + PyObject *exc, + int ierr, + const char *filename, + const char *filename2) +{ + PyObject *name = filename ? PyUnicode_DecodeFSDefault(filename) : NULL; + PyObject *name2 = filename2 ? PyUnicode_DecodeFSDefault(filename2) : NULL; + PyObject *ret = PyErr_SetExcFromWindowsErrWithFilenameObjects(exc, + ierr, + name, + name2); + Py_XDECREF(name); + Py_XDECREF(name2); + return ret; +} + PyObject *PyErr_SetExcFromWindowsErrWithUnicodeFilename( PyObject *exc, int ierr, @@ -611,31 +679,69 @@ PyObject *PyErr_SetExcFromWindowsErrWithUnicodeFilename( PyObject *name = filename ? PyUnicode_FromUnicode(filename, wcslen(filename)) : NULL; - PyObject *ret = PyErr_SetExcFromWindowsErrWithFilenameObject(exc, + PyObject *ret = PyErr_SetExcFromWindowsErrWithFilenameObjects(exc, + ierr, + name, + NULL); + Py_XDECREF(name); + return ret; +} + +PyObject *PyErr_SetExcFromWindowsErrWithUnicodeFilenames( + PyObject *exc, + int ierr, + const Py_UNICODE *filename, + const Py_UNICODE *filename2) +{ + PyObject *name = filename ? + PyUnicode_FromUnicode(filename, wcslen(filename)) : + NULL; + PyObject *name2 = filename2 ? + PyUnicode_FromUnicode(filename2, wcslen(filename2)) : + NULL; + PyObject *ret = PyErr_SetExcFromWindowsErrWithFilenameObjects(exc, ierr, - name); + name, + name2); Py_XDECREF(name); + Py_XDECREF(name2); return ret; } PyObject *PyErr_SetExcFromWindowsErr(PyObject *exc, int ierr) { - return PyErr_SetExcFromWindowsErrWithFilename(exc, ierr, NULL); + return PyErr_SetExcFromWindowsErrWithFilenames(exc, ierr, NULL, NULL); } PyObject *PyErr_SetFromWindowsErr(int ierr) { - return PyErr_SetExcFromWindowsErrWithFilename(PyExc_OSError, - ierr, NULL); + return PyErr_SetExcFromWindowsErrWithFilenames(PyExc_OSError, + ierr, NULL, NULL); +} + +PyObject *PyErr_SetFromWindowsErrWithFilenames( + int ierr, + const char *filename, + const char *filename2) +{ + PyObject *name = filename ? PyUnicode_DecodeFSDefault(filename) : NULL; + PyObject *name2 = filename2 ? PyUnicode_DecodeFSDefault(filename2) : NULL; + PyObject *result = PyErr_SetExcFromWindowsErrWithFilenameObjects( + PyExc_OSError, + ierr, name, name2); + Py_XDECREF(name); + Py_XDECREF(name2); + return result; } + PyObject *PyErr_SetFromWindowsErrWithFilename( int ierr, const char *filename) { PyObject *name = filename ? PyUnicode_DecodeFSDefault(filename) : NULL; - PyObject *result = PyErr_SetExcFromWindowsErrWithFilenameObject( + PyObject *result = PyErr_SetExcFromWindowsErrWithFilenameObjects( PyExc_OSError, - ierr, name); + ierr, name, NULL); Py_XDECREF(name); return result; } @@ -647,10 +753,29 @@ PyObject *PyErr_SetFromWindowsErrWithUnicodeFilename( PyObject *name = filename ? PyUnicode_FromUnicode(filename, wcslen(filename)) : NULL; - PyObject *result = PyErr_SetExcFromWindowsErrWithFilenameObject( + PyObject *result = PyErr_SetExcFromWindowsErrWithFilenameObjects( + PyExc_OSError, + ierr, name, NULL); + Py_XDECREF(name); + return result; +} + +PyObject *PyErr_SetFromWindowsErrWithUnicodeFilenames( + int ierr, + const Py_UNICODE *filename, + const Py_UNICODE *filename2) +{ + PyObject *name = filename ? + PyUnicode_FromUnicode(filename, wcslen(filename)) : + NULL; + PyObject *name2 = filename2 ? + PyUnicode_FromUnicode(filename2, wcslen(filename2)) : + NULL; + PyObject *result = PyErr_SetExcFromWindowsErrWithFilenameObjects( PyExc_OSError, - ierr, name); + ierr, name, name2); Py_XDECREF(name); + Py_XDECREF(name2); return result; } #endif /* MS_WINDOWS */ |