From 19052a11314e7be7ba003fd6cdbb5400a5d77d96 Mon Sep 17 00:00:00 2001 From: Zackery Spytz Date: Mon, 9 Sep 2019 03:35:08 -0600 Subject: [PATCH] bpo-37705: Improve the implementation of winerror_to_errno() (GH-15623) winerror_to_errno() is no longer automatically generated. Do not rely on the old _dosmapperr() function. Add ERROR_NO_UNICODE_TRANSLATION (1113) -> EILSEQ. --- .../2019-08-30-15-15-22.bpo-37705.2o4NWW.rst | 1 + PC/errmap.h | 214 +++++++++++------- PC/generrmap.c | 32 --- 3 files changed, 138 insertions(+), 109 deletions(-) create mode 100644 Misc/NEWS.d/next/Windows/2019-08-30-15-15-22.bpo-37705.2o4NWW.rst delete mode 100644 PC/generrmap.c diff --git a/Misc/NEWS.d/next/Windows/2019-08-30-15-15-22.bpo-37705.2o4NWW.rst b/Misc/NEWS.d/next/Windows/2019-08-30-15-15-22.bpo-37705.2o4NWW.rst new file mode 100644 index 00000000000..a374c3a2965 --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2019-08-30-15-15-22.bpo-37705.2o4NWW.rst @@ -0,0 +1 @@ +Improve the implementation of ``winerror_to_errno()``. diff --git a/PC/errmap.h b/PC/errmap.h index 985f673a464..a7489ab75c6 100644 --- a/PC/errmap.h +++ b/PC/errmap.h @@ -1,80 +1,140 @@ -/* Generated file. Do not edit. */ -int winerror_to_errno(int winerror) +int +winerror_to_errno(int winerror) { - switch(winerror) { - case 2: return 2; - case 3: return 2; - case 4: return 24; - case 5: return 13; - case 6: return 9; - case 7: return 12; - case 8: return 12; - case 9: return 12; - case 10: return 7; - case 11: return 8; - case 15: return 2; - case 16: return 13; - case 17: return 18; - case 18: return 2; - case 19: return 13; - case 20: return 13; - case 21: return 13; - case 22: return 13; - case 23: return 13; - case 24: return 13; - case 25: return 13; - case 26: return 13; - case 27: return 13; - case 28: return 13; - case 29: return 13; - case 30: return 13; - case 31: return 13; - case 32: return 13; - case 33: return 13; - case 34: return 13; - case 35: return 13; - case 36: return 13; - case 53: return 2; - case 65: return 13; - case 67: return 2; - case 80: return 17; - case 82: return 13; - case 83: return 13; - case 89: return 11; - case 108: return 13; - case 109: return 32; - case 112: return 28; - case 114: return 9; - case 128: return 10; - case 129: return 10; - case 130: return 9; - case 132: return 13; - case 145: return 41; - case 158: return 13; - case 161: return 2; - case 164: return 11; - case 167: return 13; - case 183: return 17; - case 188: return 8; - case 189: return 8; - case 190: return 8; - case 191: return 8; - case 192: return 8; - case 193: return 8; - case 194: return 8; - case 195: return 8; - case 196: return 8; - case 197: return 8; - case 198: return 8; - case 199: return 8; - case 200: return 8; - case 201: return 8; - case 202: return 8; - case 206: return 2; - case 215: return 11; - case 232: return 32; - case 267: return 20; - case 1816: return 12; - default: return EINVAL; + // Unwrap FACILITY_WIN32 HRESULT errors. + if ((winerror & 0xFFFF0000) == 0x80070000) { + winerror &= 0x0000FFFF; + } + + // Winsock error codes (10000-11999) are errno values. + if (winerror >= 10000 && winerror < 12000) { + switch (winerror) { + case WSAEINTR: + case WSAEBADF: + case WSAEACCES: + case WSAEFAULT: + case WSAEINVAL: + case WSAEMFILE: + // Winsock definitions of errno values. See WinSock2.h + return winerror - 10000; + default: + return 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; } } diff --git a/PC/generrmap.c b/PC/generrmap.c deleted file mode 100644 index 953344c0d79..00000000000 --- a/PC/generrmap.c +++ /dev/null @@ -1,32 +0,0 @@ -#include -#include -#include -#include -#include - -/* Extract the mapping of Win32 error codes to errno */ - -int main() -{ - int i; - _setmode(fileno(stdout), O_BINARY); - printf("/* Generated file. Do not edit. */\n"); - printf("int winerror_to_errno(int winerror)\n"); - printf("{\n switch(winerror) {\n"); - for(i=1; i < 65000; i++) { - _dosmaperr(i); - if (errno == EINVAL) { - /* Issue #12802 */ - if (i == ERROR_DIRECTORY) - errno = ENOTDIR; - /* Issue #13063 */ - else if (i == ERROR_NO_DATA) - errno = EPIPE; - else - continue; - } - printf(" case %d: return %d;\n", i, errno); - } - printf(" default: return EINVAL;\n"); - printf(" }\n}\n"); -}