| |
| #include <stdio.h> |
| #include <windows.h> |
| #include <errno.h> |
| #include <stdlib.h> |
| |
| /* This is the error table that defines the mapping between OS error |
| codes and errno values */ |
| |
| struct errentry { |
| unsigned long int oserrcode; /* OS return value */ |
| int errnocode; /* System V error code */ |
| }; |
| |
| static struct errentry errtable[] = { |
| { ERROR_SUCCESS, 0 }, /* 0 */ |
| { ERROR_INVALID_FUNCTION, EINVAL }, /* 1 */ |
| { ERROR_FILE_NOT_FOUND, ENOENT }, /* 2 */ |
| { ERROR_PATH_NOT_FOUND, ENOENT }, /* 3 */ |
| { ERROR_TOO_MANY_OPEN_FILES, EMFILE }, /* 4 */ |
| { ERROR_ACCESS_DENIED, EACCES }, /* 5 */ |
| { ERROR_INVALID_HANDLE, EBADF }, /* 6 */ |
| { ERROR_ARENA_TRASHED, ENOMEM }, /* 7 */ |
| { ERROR_NOT_ENOUGH_MEMORY, ENOMEM }, /* 8 */ |
| { ERROR_INVALID_BLOCK, ENOMEM }, /* 9 */ |
| { ERROR_BAD_ENVIRONMENT, E2BIG }, /* 10 */ |
| { ERROR_BAD_FORMAT, ENOEXEC }, /* 11 */ |
| { ERROR_INVALID_ACCESS, EINVAL }, /* 12 */ |
| { ERROR_INVALID_DATA, EINVAL }, /* 13 */ |
| { ERROR_INVALID_DRIVE, ENOENT }, /* 15 */ |
| { ERROR_CURRENT_DIRECTORY, EACCES }, /* 16 */ |
| { ERROR_NOT_SAME_DEVICE, EXDEV }, /* 17 */ |
| { ERROR_NO_MORE_FILES, ENOENT }, /* 18 */ |
| { ERROR_LOCK_VIOLATION, EACCES }, /* 33 */ |
| { ERROR_BAD_NETPATH, ENOENT }, /* 53 */ |
| { ERROR_NETWORK_ACCESS_DENIED, EACCES }, /* 65 */ |
| { ERROR_BAD_NET_NAME, ENOENT }, /* 67 */ |
| { ERROR_FILE_EXISTS, EEXIST }, /* 80 */ |
| { ERROR_CANNOT_MAKE, EACCES }, /* 82 */ |
| { ERROR_FAIL_I24, EACCES }, /* 83 */ |
| { ERROR_INVALID_PARAMETER, EINVAL }, /* 87 */ |
| { ERROR_NO_PROC_SLOTS, EAGAIN }, /* 89 */ |
| { ERROR_DRIVE_LOCKED, EACCES }, /* 108 */ |
| { ERROR_BROKEN_PIPE, EPIPE }, /* 109 */ |
| { ERROR_DISK_FULL, ENOSPC }, /* 112 */ |
| { ERROR_INVALID_TARGET_HANDLE, EBADF }, /* 114 */ |
| { ERROR_INVALID_HANDLE, EINVAL }, /* 124 */ |
| { ERROR_WAIT_NO_CHILDREN, ECHILD }, /* 128 */ |
| { ERROR_CHILD_NOT_COMPLETE, ECHILD }, /* 129 */ |
| { ERROR_DIRECT_ACCESS_HANDLE, EBADF }, /* 130 */ |
| { ERROR_NEGATIVE_SEEK, EINVAL }, /* 131 */ |
| { ERROR_SEEK_ON_DEVICE, EACCES }, /* 132 */ |
| { ERROR_DIR_NOT_EMPTY, ENOTEMPTY }, /* 145 */ |
| { ERROR_NOT_LOCKED, EACCES }, /* 158 */ |
| { ERROR_BAD_PATHNAME, ENOENT }, /* 161 */ |
| { ERROR_MAX_THRDS_REACHED, EAGAIN }, /* 164 */ |
| { ERROR_LOCK_FAILED, EACCES }, /* 167 */ |
| { ERROR_ALREADY_EXISTS, EEXIST }, /* 183 */ |
| { ERROR_FILENAME_EXCED_RANGE, ENOENT }, /* 206 */ |
| { ERROR_NESTING_NOT_ALLOWED, EAGAIN }, /* 215 */ |
| { ERROR_OPERATION_ABORTED, EINTR }, /* 995 */ |
| { ERROR_NOT_ENOUGH_QUOTA, ENOMEM } /* 1816 */ |
| }; |
| |
| /* size of the table */ |
| #define ERRTABLESIZE (sizeof(errtable)/sizeof(*errtable)) |
| |
| /* The following two constants must be the minimum and maximum |
| values in the (contiguous) range of Exec Failure errors. */ |
| #define MIN_EXEC_ERROR ERROR_INVALID_STARTING_CODESEG |
| #define MAX_EXEC_ERROR ERROR_INFLOOP_IN_RELOC_CHAIN |
| |
| /* These are the low and high value in the range of errors that are |
| access violations */ |
| #define MIN_EACCES_RANGE ERROR_WRITE_PROTECT |
| #define MAX_EACCES_RANGE ERROR_SHARING_BUFFER_EXCEEDED |
| |
| static int __cdecl _get_errno_from_oserr(unsigned long int oserrno) { |
| int i; |
| |
| /* check the table for the OS error code */ |
| for(i = 0; i < ERRTABLESIZE; i++) { |
| if(oserrno == errtable[i].oserrcode) { |
| return errtable[i].errnocode; |
| } |
| } |
| |
| /* The error code wasn't in the table. We check for a range of */ |
| /* EACCES errors or exec failure errors (ENOEXEC). Otherwise */ |
| /* EINVAL is returned. */ |
| if(oserrno >= MIN_EACCES_RANGE && oserrno <= MAX_EACCES_RANGE) return EACCES; |
| else if(oserrno >= MIN_EXEC_ERROR && oserrno <= MAX_EXEC_ERROR) return ENOEXEC; |
| else return EINVAL; |
| } |
| |
| static int new_errno = 0; |
| |
| /* |
| int oserror_to_errno(unsigned long int errorcode) { |
| new_errno = _get_errno_from_oserr(errorcode); |
| return new_errno; |
| }*/ |
| |
| int *__cdecl _errno() { |
| if(GetLastError() != 0xFFFFFFFF) { |
| new_errno = _get_errno_from_oserr(GetLastError()); |
| SetLastError(0xFFFFFFFF); |
| } |
| return &new_errno; |
| } |