]> granicus.if.org Git - python/commitdiff
Patch by Mark Hammond:
authorGuido van Rossum <guido@python.org>
Thu, 17 Feb 2000 15:19:15 +0000 (15:19 +0000)
committerGuido van Rossum <guido@python.org>
Thu, 17 Feb 2000 15:19:15 +0000 (15:19 +0000)
* 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.

Python/errors.c

index cb0503b402f70042b9b8a2f31a297eb4a4a94ff6..71e51c30233e6673a3752f52bf7f1d6dea969c83 100644 (file)
@@ -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()
 {