diff options
author | Guido van Rossum <guido@python.org> | 2000-02-17 15:19:15 (GMT) |
---|---|---|
committer | Guido van Rossum <guido@python.org> | 2000-02-17 15:19:15 (GMT) |
commit | 795e189d28f7afd9f4e864a998658e3302efb59e (patch) | |
tree | 17c75582dcf539202522db81df614961a9eea76e /Python | |
parent | 65a75b0d52e840fcb2ab19281570d7abdbf7ef08 (diff) | |
download | cpython-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')
-rw-r--r-- | Python/errors.c | 90 |
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() { |