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.
This commit is contained in:
parent
65a75b0d52
commit
795e189d28
|
@ -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()
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue