Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 795e189

Browse files
committed
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.
1 parent 65a75b0 commit 795e189

1 file changed

Lines changed: 75 additions & 15 deletions

File tree

Python/errors.c

Lines changed: 75 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,9 @@ PyErr_SetFromErrnoWithFilename(exc, filename)
289289
PyObject *v;
290290
char *s;
291291
int i = errno;
292+
#ifdef MS_WIN32
293+
char *s_buf = NULL;
294+
#endif
292295
#ifdef EINTR
293296
if (i == EINTR && PyErr_CheckSignals())
294297
return NULL;
@@ -300,20 +303,32 @@ PyErr_SetFromErrnoWithFilename(exc, filename)
300303
s = strerror(i);
301304
#else
302305
{
303-
int len = FormatMessage(
304-
FORMAT_MESSAGE_ALLOCATE_BUFFER |
305-
FORMAT_MESSAGE_FROM_SYSTEM |
306-
FORMAT_MESSAGE_IGNORE_INSERTS,
307-
NULL, /* no message source */
308-
i,
309-
MAKELANGID(LANG_NEUTRAL,
310-
SUBLANG_DEFAULT), /* Default language */
311-
(LPTSTR) &s,
312-
0, /* size not used */
313-
NULL); /* no args */
314-
/* remove trailing cr/lf and dots */
315-
while (len > 0 && s[len-1] <= '.')
316-
s[--len] = '\0';
306+
/* Note that the Win32 errors do not lineup with the
307+
errno error. So if the error is in the MSVC error
308+
table, we use it, otherwise we assume it really _is_
309+
a Win32 error code
310+
*/
311+
if (i < _sys_nerr) {
312+
s = _sys_errlist[i];
313+
}
314+
else {
315+
int len = FormatMessage(
316+
FORMAT_MESSAGE_ALLOCATE_BUFFER |
317+
FORMAT_MESSAGE_FROM_SYSTEM |
318+
FORMAT_MESSAGE_IGNORE_INSERTS,
319+
NULL, /* no message source */
320+
i,
321+
MAKELANGID(LANG_NEUTRAL,
322+
SUBLANG_DEFAULT),
323+
/* Default language */
324+
(LPTSTR) &s_buf,
325+
0, /* size not used */
326+
NULL); /* no args */
327+
s = s_buf;
328+
/* remove trailing cr/lf and dots */
329+
while (len > 0 && (s[len-1] <= ' ' || s[len-1] == '.'))
330+
s[--len] = '\0';
331+
}
317332
}
318333
#endif
319334
if (filename != NULL && Py_UseClassExceptionsFlag)
@@ -325,7 +340,7 @@ PyErr_SetFromErrnoWithFilename(exc, filename)
325340
Py_DECREF(v);
326341
}
327342
#ifdef MS_WIN32
328-
LocalFree(s);
343+
LocalFree(s_buf);
329344
#endif
330345
return NULL;
331346
}
@@ -338,6 +353,51 @@ PyErr_SetFromErrno(exc)
338353
return PyErr_SetFromErrnoWithFilename(exc, NULL);
339354
}
340355

356+
#ifdef MS_WINDOWS
357+
/* Windows specific error code handling */
358+
PyObject *PyErr_SetFromWindowsErrWithFilename(
359+
int ierr,
360+
const char *filename)
361+
{
362+
int len;
363+
char *s;
364+
PyObject *v;
365+
DWORD err = (DWORD)ierr;
366+
if (err==0) err = GetLastError();
367+
len = FormatMessage(
368+
/* Error API error */
369+
FORMAT_MESSAGE_ALLOCATE_BUFFER |
370+
FORMAT_MESSAGE_FROM_SYSTEM |
371+
FORMAT_MESSAGE_IGNORE_INSERTS,
372+
NULL, /* no message source */
373+
err,
374+
MAKELANGID(LANG_NEUTRAL,
375+
SUBLANG_DEFAULT), /* Default language */
376+
(LPTSTR) &s,
377+
0, /* size not used */
378+
NULL); /* no args */
379+
/* remove trailing cr/lf and dots */
380+
while (len > 0 && (s[len-1] <= ' ' || s[len-1] == '.'))
381+
s[--len] = '\0';
382+
if (filename != NULL && Py_UseClassExceptionsFlag)
383+
v = Py_BuildValue("(iss)", err, s, filename);
384+
else
385+
v = Py_BuildValue("(is)", err, s);
386+
if (v != NULL) {
387+
PyErr_SetObject(PyExc_EnvironmentError, v);
388+
Py_DECREF(v);
389+
}
390+
LocalFree(s);
391+
return NULL;
392+
}
393+
394+
PyObject *PyErr_SetFromWindowsErr(int ierr)
395+
{
396+
return PyErr_SetFromWindowsErrWithFilename(ierr, NULL);
397+
398+
}
399+
#endif /* MS_WINDOWS */
400+
341401
void
342402
PyErr_BadInternalCall()
343403
{

0 commit comments

Comments
 (0)