diff --git a/src/fdlib.c b/src/fdlib.c index 748d805cd2166449c2533040c25c03dfcd783b44..13625aa2db3c0335c0f0ce18d161f839b4d03fb8 100644 --- a/src/fdlib.c +++ b/src/fdlib.c @@ -99,8 +99,86 @@ static inline void libc_free(void *ptr); #define libc_free(PTR) free(PTR) #endif +#if defined(_MSC_VER) && (_MSC_VER < 1600) /* _dosmaperr is internal but still exported in the dll interface. */ __declspec(dllimport) void __cdecl _dosmaperr(unsigned long); +#else +/* msvcr100.dll seems to not implement _dosmaperr()... */ +#undef _dosmaperr +#define _dosmaperr pike_dosmaperr + +/* Mapping of Windows error codes to POSIX error codes. */ +static const unsigned long pike_doserrtab[][2] = { + { 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_NOT_ENOUGH_QUOTA, ENOMEM, }, /* 1816 */ +}; + +static inline void _dosmaperr(unsigned long err) +{ + int l = 0, h = NELEM(pike_doserrtab); + int m; + while (l < h) { + int m = (l+h)>>1; + int e = pike_doserrtab[m][0]; + + if (e == err) { + errno = pike_doserrtab[m][1]; + return; + } + + if (e < err) { + l = m+1; + } else { + h = m; + } + } + errno = EINVAL; +} + +#endif PMOD_EXPORT void set_errno_from_win32_error (unsigned long err) {