[MLton-commit] r7498
Wesley Terpstra
wesley at mlton.org
Tue Jul 6 09:24:19 PDT 2010
FormatMessage doesn't agree with strerror.
It also gives poor strings back for networking related errors.
Augment MinGW's native strerror with a big network-specific lookup table.
----------------------------------------------------------------------
U mlton/trunk/runtime/platform/mingw.c
----------------------------------------------------------------------
Modified: mlton/trunk/runtime/platform/mingw.c
===================================================================
--- mlton/trunk/runtime/platform/mingw.c 2010-06-22 13:27:35 UTC (rev 7497)
+++ mlton/trunk/runtime/platform/mingw.c 2010-07-06 16:24:18 UTC (rev 7498)
@@ -1308,26 +1308,75 @@
}
}
-/* The default strerror() does not know extended error codes. */
+static const char *MLton_strerrorExtension(int code) {
+ switch (code) {
+ case EINTR: return "Interrupted function call";
+ case EBADF: return "Bad file descriptor";
+ case EACCES: return "Permission denied";
+ case EFAULT: return "Bad address";
+ case EINVAL: return "Invalid argument";
+ case EMFILE: return "Too many open files";
+ case EAGAIN: return "Resource temporarily unavailable";
+ case EINPROGRESS: return "Operation in progress";
+ case EALREADY: return "Connection already in progress";
+ case ENOTSOCK: return "Not a socket";
+ case EDESTADDRREQ: return "Destination address required";
+ case EMSGSIZE: return "Message too long";
+ case EPROTOTYPE: return "Protocol wrong type for socket";
+ case ENOPROTOOPT: return "Protocol not available";
+ case EPROTONOSUPPORT: return "Protocol not supported";
+ case ESOCKTNOSUPPORT: return "Socket type not supported";
+ case EOPNOTSUPP: return "Operation not supported on socket";
+ case EPFNOSUPPORT: return "Protocol family not supported";
+ case EAFNOSUPPORT: return "Address family not supported";
+ case EADDRINUSE: return "Address already in use";
+ case EADDRNOTAVAIL: return "Address not available";
+ case ENETDOWN: return "Network is down";
+ case ENETUNREACH: return "Network unreachable";
+ case ENETRESET: return "Connection aborted by network";
+ case ECONNABORTED: return "Connection aborted";
+ case ECONNRESET: return "Connection reset";
+ case ENOBUFS: return "No buffer space available";
+ case EISCONN: return "Socket is connected";
+ case ENOTCONN: return "The socket is not connected";
+ case ESHUTDOWN: return "Cannot send after transport endpoint shutdown";
+ case ETIMEDOUT: return "Connection timed out";
+ case ECONNREFUSED: return "Connection refused";
+ case ELOOP: return "Too many levels of symbolic links";
+ case ENAMETOOLONG: return "Filename too long";
+ case EHOSTDOWN: return "Host is down";
+ case EHOSTUNREACH: return "Host is unreachable";
+ case ENOTEMPTY: return "Directory not empty";
+ case EDQUOT: return "Disk quota exceeded";
+ case ESTALE: return "Stale file handle";
+ case EREMOTE: return "Object is remote";
+ case EUSERS: return "Too many users";
+ case ECANCELED: return "Operation canceled";
+ default: return "Unknown error";
+ }
+}
+
+/* MinGW strerror works for all system-defined errno values.
+ * However, platform/mingw.h adds some missing POSIX networking error codes.
+ * It defines these codes as their closest-equivalent winsock error code.
+ * To report network errors, MLton_fixSocketErrno maps winsock errors to
+ * their closest POSIX errno value.
+ *
+ * This function must handle the winsock errno values we have added.
+ * FormatMessage doesn't return the POSIX string for errors, and it uses
+ * the current locale's language. The MinGW strerror is always English.
+ *
+ * Thus, we just make a big English table to augment strerror.
+ * The descriptions are taken from man errno(3).
+ */
char *MLton_strerror(int code) {
- static char buffer[512];
+ static char buffer[80];
- /* Windows specific strerror */
- if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
- 0, /* Not used for FROM_SYSTEM */
- code, /* The status code to look up */
- 0, /* Use the default language */
- buffer, /* Write the message to here */
- sizeof(buffer)-1,
- 0) == 0) {
- strcpy(buffer, "Unknown error");
- }
-
- /* Cut message at EOL */
- for (int i = 0; buffer[i]; ++i)
- if (buffer[i] == '\n' || buffer[i] == '\r')
- buffer[i] = 0;
-
+#undef strerror
+ if (code < sys_nerr) return strerror(code);
+#define strerror MLton_strerror
+
+ strcpy(buffer, MLton_strerrorExtension(code));
return buffer;
}
More information about the MLton-commit
mailing list