[MLton] Bug in implementation of "strerror" on MinGW

Nicolas Bertolotti Nicolas.Bertolotti at mathworks.fr
Tue Jul 6 10:24:40 PDT 2010


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: mlton-bounces at mlton.org [mailto:mlton-bounces at mlton.org] On
> Behalf Of Wesley W. Terpstra
> Sent: Tuesday, July 06, 2010 5:46 PM
> To: mlton at mlton.org
> Subject: Re: [MLton] Bug in implementation of "strerror" on MinGW
> 
> On Tue, Jul 6, 2010 at 3:07 PM, Nicolas Bertolotti
> <Nicolas.Bertolotti at mathworks.fr> 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
> MLton at mlton.org
> http://mlton.org/mailman/listinfo/mlton



More information about the MLton mailing list