RE: Bug in implementation of "strerror" on MinGW
Nicolas Bertolotti <[email protected]>
| Newsgroups | gmane.comp.lang.ml.mlton.devel |
|---|---|
| Message-ID | <8320D98DA9A5C54C926D397795FE7CEA84598E8904@EXCHANGE-UK.ad.mathworks.com> |
Yes, sorry, the fix was definitely buggy. I finally added a #define MLTON_MINGW at the beginning of the file and encapsulated the: #define strerror MLton_strerror in a #if (! defined(MLTON_UTIL)) && (! defined(MLTON_MINGW)) in order to use the same trick than the one used to build util.c and really call 'strerror()'. I somehow like the fact that FormatMessage() speaks French, german or English depending on the machine language. I wonder whether it would be possible to convert the errno values to a system error code equivalent and then always call FormatMessage() though it would not be perfect because it is not a one to one mapping. Something like that ? EPERM [Operation not permitted] -> ERROR_ACCESS_DENIED ENOENT [No such file or directory] -> ERROR_PATH_NOT_FOUND ESRCH [No such process] -> ERROR_INVALID_PARAMETER EINTR [Interrupted function] -> ERROR_OPERATION_ABORTED EIO [I/O error] -> ERROR_IO_DEVICE ENXIO [No such device or address] -> ERROR_BAD_UNIT E2BIG [Argument list too long] -> ERROR_BAD_ARGUMENTS ENOEXEC [Exec format error] -> ERROR_BAD_FORMAT EBADF [Bad file number] -> ERROR_INVALID_HANDLE ECHILD [No spawned processes] -> ERROR_WAIT_NO_CHILDREN EAGAIN [No more processes or not enough memory or maximum nesting level reached] -> ERROR_MAX_THRDS_REACHED ENOMEM [Not enough memory] -> ERROR_NOT_ENOUGH_MEMORY EACCES [Permission denied] -> ERROR_ACCESS_DENIED EFAULT [Bad address] -> ERROR_INVALID_ADDRESS EBUSY [Device or resource busy] -> ERROR_BUSY EEXIST [File exists] -> ERROR_FILE_EXISTS EXDEV [Cross-device link] -> ERROR_NOT_SAME_DEVICE ENODEV [No such device] -> ERROR_BAD_UNIT ENOTDIR [Not a directory] -> ERROR_DIRECTORY EISDIR [Is a directory] -> ERROR_FILE_EXISTS EINVAL [Invalid argument] -> ERROR_BAD_ARGUMENTS ENFILE [Too many files open in system] -> ERROR_TOO_MANY_OPEN_FILES EMFILE [Too many open files] -> ERROR_TOO_MANY_OPEN_FILES ENOTTY [Inappropriate I/O control operation] -> ERROR_INVALID_CATEGORY EFBIG [File too large] -> ERROR_FILE_TOO_LARGE ENOSPC [No space left on device] -> ERROR_HANDLE_DISK_FULL ESPIPE [Invalid seek] -> ERROR_SEEK EROFS [Read-only file system] -> ERROR_WRITE_PROTECT EMLINK [Too many links] -> ERROR_TOO_MANY_LINKS EPIPE [Broken pipe] -> ERROR_BROKEN_PIPE EDOM [Math argument] -> ERROR_FLOAT_MULTIPLE_FAULTS ERANGE [Result too large] -> ERROR_ARITHMETIC_OVERFLOW EDEADLK [Resource deadlock would occur] -> ERROR_POSSIBLE_DEADLOCK EDEADLOCK [Same as EDEADLK for compatibility with older Microsoft C versions] -> ERROR_POSSIBLE_DEADLOCK ENAMETOOLONG [Filename too long] -> ERROR_BUFFER_OVERFLOW ENOLCK [No locks available] -> ERROR_LOCK_FAILED ENOSYS [Function not supported] -> ERROR_NOT_SUPPORTED ENOTEMPTY [Directory not empty] -> ERROR_DIR_NOT_EMPTY EILSEQ [Illegal byte sequence] -> ERROR_ILLEGAL_CHARACTER Nicolas > -----Original Message----- > From: [email protected] [mailto:[email protected]] On > Behalf Of Wesley W. Terpstra > Sent: Tuesday, July 06, 2010 5:46 PM > To: [email protected] > Subject: Re: [MLton] Bug in implementation of "strerror" on MinGW > > On Tue, Jul 6, 2010 at 3:07 PM, Nicolas Bertolotti > <[email protected]> wrote: > > For example, with ENOSPC, strerror() should return "No space left on > device". Anyway, the MLton implementation returns "The printer is out > of paper" because the "errno" value does not have the same meaning than > the corresponding system error code on Windows. > > Hah! > > > If you are absolutely sure that the extended error codes that have > been introduced will not conflict with the existing "errno" values... > > Ok, so I've done a bit of checking. According to > <http://msdn.microsoft.com/en-us/library/aa924071.aspx>, the winsock > error codes are all above 10000, so your proposed fix should work. > Furthermore, 'curl' does this in its strerror.c > > A bit of background: Revision 7196 extended the values for errno to > add the missing errno status codes as required by the basis' > networking support. It defined these in terms of the winsock codes if > there was not an existing errno code defined. There's a big table that > maps the winsock errors to their closest POSIX analogue called > MLton_fixSocketErrno. > > With regards to your fix: > It seems safe to assume existing errno codes (< sys_nerr) have a > matching result in strerror > The added errno codes in mingw.h are defined in terms of WSAERR<X>, > so FormatError will work (and they all have values over 10000) > Thus, your solution should be correct (though _strerror is the wrong > method). > > There is another problem with using a mixture of strerror and > FormatError, though. strerror always returns English. FormatMessage > uses the user's locale. Also, the FormatMessage error strings in both > english and german are absurd. EADDRINUSE isn't "Address in use", but > something like "Normally a network resource (address/port/protocol) > can only be used once at the same time." ... curl wrote a big lookup > table with the usual posix error strings. I'm considering doing the > same. > > _______________________________________________ > MLton mailing list > [email protected] > http://mlton.org/mailman/listinfo/mlton