summaryrefslogtreecommitdiffstats
path: root/Python/errors.c
diff options
context:
space:
mode:
authorLarry Hastings <larry@hastings.org>2014-02-10 06:05:19 (GMT)
committerLarry Hastings <larry@hastings.org>2014-02-10 06:05:19 (GMT)
commitb082731fbb413a7ff2412a447698fdd65015fd24 (patch)
tree6cb37b4aacee0af28c057079af5545cf92dd1537 /Python/errors.c
parentdc62b7e261ab88b4ab967ac2ae307eddbfa0ae09 (diff)
downloadcpython-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.c169
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 */