Author eryksun
Recipients eryksun, paul.moore, steve.dower, tim.golden, zach.ware
Date 2019-07-29.13:41:00
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1564407660.89.0.454912973453.issue37705@roundup.psfhosted.org>
In-reply-to
Content
OSError and _Py_fstat_noraise rely on winerror_to_errno() in PC/errmap.h in order to translate a Windows system error code into a POSIX errno value. PC/errmap.h is supposed to be generated by PC/generrmap.c, which is based on the old CRT's _dosmapperr() function. However, this function isn't implemented in the Universal CRT, and ucrt's corresponding function, __acrt_errno_from_os_error, isn't exported for public use.

If generrmap.c is effectively dead, then it's no longer possible to add custom mappings there, as was done for issue 12802 (ERROR_DIRECTORY -> ENOTDIR) and issue 13063 (ERROR_NO_DATA -> EPIPE). Also, errmap.h hasn't been regenerated in 8 years, and since then the CRT added a new mapped value: ERROR_NO_UNICODE_TRANSLATION (1113) -> EILSEQ. 

Unless someone can suggest a way to continue automatically generating errmap.h via generrmap.c, then I think winerror_to_errno should be manually implemented in a more readable and maintainable way, and updated from the ucrt source (ucrt\misc\errno.cpp) with each major Python release. The implementation could use a switch statement like it currently does, but with named error codes, grouped by result. For example:

    int
    winerror_to_errno(int winerror)
    {
        switch(winerror) {
        case ERROR_FILE_NOT_FOUND:            //    2
        case ERROR_PATH_NOT_FOUND:            //    3
        case ERROR_INVALID_DRIVE:             //   15
        case ERROR_NO_MORE_FILES:             //   18
        case ERROR_BAD_NETPATH:               //   53
        case ERROR_BAD_NET_NAME:              //   67
        case ERROR_BAD_PATHNAME:              //  161
        case ERROR_FILENAME_EXCED_RANGE:      //  206
            return ENOENT;

        case ERROR_BAD_ENVIRONMENT:           //   10
            return E2BIG;

        case ERROR_BAD_FORMAT:                //   11
        case ERROR_INVALID_STARTING_CODESEG:  //  188
        case ERROR_INVALID_STACKSEG:          //  189
        case ERROR_INVALID_MODULETYPE:        //  190
        case ERROR_INVALID_EXE_SIGNATURE:     //  191
        case ERROR_EXE_MARKED_INVALID:        //  192
        case ERROR_BAD_EXE_FORMAT:            //  193
        case ERROR_ITERATED_DATA_EXCEEDS_64k: //  194
        case ERROR_INVALID_MINALLOCSIZE:      //  195
        case ERROR_DYNLINK_FROM_INVALID_RING: //  196
        case ERROR_IOPL_NOT_ENABLED:          //  197
        case ERROR_INVALID_SEGDPL:            //  198
        case ERROR_AUTODATASEG_EXCEEDS_64k:   //  199
        case ERROR_RING2SEG_MUST_BE_MOVABLE:  //  200
        case ERROR_RELOC_CHAIN_XEEDS_SEGLIM:  //  201
        case ERROR_INFLOOP_IN_RELOC_CHAIN:    //  202
            return ENOEXEC;

        case ERROR_INVALID_HANDLE:            //    6
        case ERROR_INVALID_TARGET_HANDLE:     //  114
        case ERROR_DIRECT_ACCESS_HANDLE:      //  130
            return EBADF;

        case ERROR_WAIT_NO_CHILDREN:          //  128
        case ERROR_CHILD_NOT_COMPLETE:        //  129
            return ECHILD;

        case ERROR_NO_PROC_SLOTS:             //   89
        case ERROR_MAX_THRDS_REACHED:         //  164
        case ERROR_NESTING_NOT_ALLOWED:       //  215
            return EAGAIN;

        case ERROR_ARENA_TRASHED:             //    7
        case ERROR_NOT_ENOUGH_MEMORY:         //    8
        case ERROR_INVALID_BLOCK:             //    9
        case ERROR_NOT_ENOUGH_QUOTA:          // 1816
            return ENOMEM;

        case ERROR_ACCESS_DENIED:             //    5
        case ERROR_CURRENT_DIRECTORY:         //   16
        case ERROR_WRITE_PROTECT:             //   19
        case ERROR_BAD_UNIT:                  //   20
        case ERROR_NOT_READY:                 //   21
        case ERROR_BAD_COMMAND:               //   22
        case ERROR_CRC:                       //   23
        case ERROR_BAD_LENGTH:                //   24
        case ERROR_SEEK:                      //   25
        case ERROR_NOT_DOS_DISK:              //   26
        case ERROR_SECTOR_NOT_FOUND:          //   27
        case ERROR_OUT_OF_PAPER:              //   28
        case ERROR_WRITE_FAULT:               //   29
        case ERROR_READ_FAULT:                //   30
        case ERROR_GEN_FAILURE:               //   31
        case ERROR_SHARING_VIOLATION:         //   32
        case ERROR_LOCK_VIOLATION:            //   33
        case ERROR_WRONG_DISK:                //   34
        case ERROR_SHARING_BUFFER_EXCEEDED:   //   36
        case ERROR_NETWORK_ACCESS_DENIED:     //   65
        case ERROR_CANNOT_MAKE:               //   82
        case ERROR_FAIL_I24:                  //   83
        case ERROR_DRIVE_LOCKED:              //  108
        case ERROR_SEEK_ON_DEVICE:            //  132
        case ERROR_NOT_LOCKED:                //  158
        case ERROR_LOCK_FAILED:               //  167
        case 35:                              //   35 [undefined]
            return EACCES;

        case ERROR_FILE_EXISTS:               //   80
        case ERROR_ALREADY_EXISTS:            //  183
            return EEXIST;

        case ERROR_NOT_SAME_DEVICE:           //   17
            return EXDEV;

        case ERROR_DIRECTORY:                 //  267 [bpo-12802]
            return ENOTDIR;

        case ERROR_TOO_MANY_OPEN_FILES:       //    4
            return EMFILE;

        case ERROR_DISK_FULL:                 //  112
            return ENOSPC;

        case ERROR_BROKEN_PIPE:               //  109
        case ERROR_NO_DATA:                   //  232 [bpo-13063]
            return EPIPE;

        case ERROR_DIR_NOT_EMPTY:             //  145
            return ENOTEMPTY;

        case ERROR_NO_UNICODE_TRANSLATION:    // 1113
            return EILSEQ;

        case ERROR_INVALID_FUNCTION:          //    1
        case ERROR_INVALID_ACCESS:            //   12
        case ERROR_INVALID_DATA:              //   13
        case ERROR_INVALID_PARAMETER:         //   87
        case ERROR_NEGATIVE_SEEK:             //  131
        default:
            return EINVAL;
        }
    }
History
Date User Action Args
2019-07-29 13:41:00eryksunsetrecipients: + eryksun, paul.moore, tim.golden, zach.ware, steve.dower
2019-07-29 13:41:00eryksunsetmessageid: <1564407660.89.0.454912973453.issue37705@roundup.psfhosted.org>
2019-07-29 13:41:00eryksunlinkissue37705 messages
2019-07-29 13:41:00eryksuncreate