summaryrefslogtreecommitdiffstats
path: root/Python/errors.c
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>2000-02-17 15:19:15 (GMT)
committerGuido van Rossum <guido@python.org>2000-02-17 15:19:15 (GMT)
commit795e189d28f7afd9f4e864a998658e3302efb59e (patch)
tree17c75582dcf539202522db81df614961a9eea76e /Python/errors.c
parent65a75b0d52e840fcb2ab19281570d7abdbf7ef08 (diff)
downloadcpython-795e189d28f7afd9f4e864a998658e3302efb59e.zip
cpython-795e189d28f7afd9f4e864a998658e3302efb59e.tar.gz
cpython-795e189d28f7afd9f4e864a998658e3302efb59e.tar.bz2
Patch by Mark Hammond:
* Changes to a recent patch by Chris Tismer to errors.c. Chris' patch always used FormatMessage() to get the error message passing the error code from errno - but errno and FormatMessage use a different numbering scheme. The main reason the patch looked OK was that ENOFILE==ERROR_FILE_NOT_FOUND - but that is about the only shared error code :-). The MS CRT docs tell you to use _sys_errlist()/_sys_nerr. My patch does also this, and adds a very similar function specifically for win32 error codes.
Diffstat (limited to 'Python/errors.c')
-rw-r--r--Python/errors.c90
1 files changed, 75 insertions, 15 deletions
diff --git a/Python/errors.c b/Python/errors.c
index cb0503b..71e51c3 100644
--- a/Python/errors.c
+++ b/Python/errors.c
@@ -289,6 +289,9 @@ PyErr_SetFromErrnoWithFilename(exc, filename)
PyObject *v;
char *s;
int i = errno;
+#ifdef MS_WIN32
+ char *s_buf = NULL;
+#endif
#ifdef EINTR
if (i == EINTR && PyErr_CheckSignals())
return NULL;
@@ -300,20 +303,32 @@ PyErr_SetFromErrnoWithFilename(exc, filename)
s = strerror(i);
#else
{
- int len = FormatMessage(
- FORMAT_MESSAGE_ALLOCATE_BUFFER |
- FORMAT_MESSAGE_FROM_SYSTEM |
- FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL, /* no message source */
- i,
- MAKELANGID(LANG_NEUTRAL,
- SUBLANG_DEFAULT), /* Default language */
- (LPTSTR) &s,
- 0, /* size not used */
- NULL); /* no args */
- /* remove trailing cr/lf and dots */
- while (len > 0 && s[len-1] <= '.')
- s[--len] = '\0';
+ /* Note that the Win32 errors do not lineup with the
+ errno error. So if the error is in the MSVC error
+ table, we use it, otherwise we assume it really _is_
+ a Win32 error code
+ */
+ if (i < _sys_nerr) {
+ s = _sys_errlist[i];
+ }
+ else {
+ int len = FormatMessage(
+ FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL, /* no message source */
+ i,
+ MAKELANGID(LANG_NEUTRAL,
+ SUBLANG_DEFAULT),
+ /* Default language */
+ (LPTSTR) &s_buf,
+ 0, /* size not used */
+ NULL); /* no args */
+ s = s_buf;
+ /* remove trailing cr/lf and dots */
+ while (len > 0 && (s[len-1] <= ' ' || s[len-1] == '.'))
+ s[--len] = '\0';
+ }
}
#endif
if (filename != NULL && Py_UseClassExceptionsFlag)
@@ -325,7 +340,7 @@ PyErr_SetFromErrnoWithFilename(exc, filename)
Py_DECREF(v);
}
#ifdef MS_WIN32
- LocalFree(s);
+ LocalFree(s_buf);
#endif
return NULL;
}
@@ -338,6 +353,51 @@ PyErr_SetFromErrno(exc)
return PyErr_SetFromErrnoWithFilename(exc, NULL);
}
+#ifdef MS_WINDOWS
+/* Windows specific error code handling */
+PyObject *PyErr_SetFromWindowsErrWithFilename(
+ int ierr,
+ const char *filename)
+{
+ int len;
+ char *s;
+ PyObject *v;
+ DWORD err = (DWORD)ierr;
+ if (err==0) err = GetLastError();
+ len = FormatMessage(
+ /* Error API error */
+ FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL, /* no message source */
+ err,
+ MAKELANGID(LANG_NEUTRAL,
+ SUBLANG_DEFAULT), /* Default language */
+ (LPTSTR) &s,
+ 0, /* size not used */
+ NULL); /* no args */
+ /* remove trailing cr/lf and dots */
+ while (len > 0 && (s[len-1] <= ' ' || s[len-1] == '.'))
+ s[--len] = '\0';
+ if (filename != NULL && Py_UseClassExceptionsFlag)
+ v = Py_BuildValue("(iss)", err, s, filename);
+ else
+ v = Py_BuildValue("(is)", err, s);
+ if (v != NULL) {
+ PyErr_SetObject(PyExc_EnvironmentError, v);
+ Py_DECREF(v);
+ }
+ LocalFree(s);
+ return NULL;
+}
+
+PyObject *PyErr_SetFromWindowsErr(int ierr)
+{
+ return PyErr_SetFromWindowsErrWithFilename(ierr, NULL);
+
+}
+#endif /* MS_WINDOWS */
+
void
PyErr_BadInternalCall()
{