andre@0: /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ andre@0: /* This Source Code Form is subject to the terms of the Mozilla Public andre@0: * License, v. 2.0. If a copy of the MPL was not distributed with this andre@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ andre@0: andre@0: #include "prerror.h" andre@0: #include "prlog.h" andre@0: #include andre@0: #include andre@0: andre@0: /* andre@0: * On Win32, we map three kinds of error codes: andre@0: * - GetLastError(): for Win32 functions andre@0: * - WSAGetLastError(): for Winsock functions andre@0: * - errno: for standard C library functions andre@0: * andre@0: * GetLastError() and WSAGetLastError() return error codes in andre@0: * non-overlapping ranges, so their error codes (ERROR_* and andre@0: * WSAE*) can be mapped by the same function. On the other hand, andre@0: * errno and GetLastError() have overlapping ranges, so we need andre@0: * to use a separate function to map errno. andre@0: * andre@0: * We do not check for WSAEINPROGRESS and WSAEINTR because we do not andre@0: * use blocking Winsock 1.1 calls. andre@0: * andre@0: * Except for the 'socket' call, we do not check for WSAEINITIALISED. andre@0: * It is assumed that if Winsock is not initialized, that fact will andre@0: * be detected at the time we create new sockets. andre@0: */ andre@0: andre@0: static void _MD_win32_map_default_errno(PRInt32 err) andre@0: { andre@0: PRErrorCode prError; andre@0: andre@0: switch (err) { andre@0: case EACCES: andre@0: prError = PR_NO_ACCESS_RIGHTS_ERROR; andre@0: break; andre@0: case ENOENT: andre@0: prError = PR_FILE_NOT_FOUND_ERROR; andre@0: break; andre@0: default: andre@0: prError = PR_UNKNOWN_ERROR; andre@0: break; andre@0: } andre@0: PR_SetError(prError, err); andre@0: } andre@0: andre@0: void _MD_win32_map_default_error(PRInt32 err) andre@0: { andre@0: PRErrorCode prError; andre@0: andre@0: switch (err) { andre@0: case ERROR_ACCESS_DENIED: andre@0: prError = PR_NO_ACCESS_RIGHTS_ERROR; andre@0: break; andre@0: case ERROR_ALREADY_EXISTS: andre@0: prError = PR_FILE_EXISTS_ERROR; andre@0: break; andre@0: case ERROR_CALL_NOT_IMPLEMENTED: andre@0: prError = PR_NOT_IMPLEMENTED_ERROR; andre@0: break; andre@0: case ERROR_DISK_CORRUPT: andre@0: prError = PR_IO_ERROR; andre@0: break; andre@0: case ERROR_DISK_FULL: andre@0: prError = PR_NO_DEVICE_SPACE_ERROR; andre@0: break; andre@0: case ERROR_DISK_OPERATION_FAILED: andre@0: prError = PR_IO_ERROR; andre@0: break; andre@0: case ERROR_DRIVE_LOCKED: andre@0: prError = PR_FILE_IS_LOCKED_ERROR; andre@0: break; andre@0: case ERROR_FILENAME_EXCED_RANGE: andre@0: prError = PR_NAME_TOO_LONG_ERROR; andre@0: break; andre@0: case ERROR_FILE_CORRUPT: andre@0: prError = PR_IO_ERROR; andre@0: break; andre@0: case ERROR_FILE_EXISTS: andre@0: prError = PR_FILE_EXISTS_ERROR; andre@0: break; andre@0: case ERROR_FILE_INVALID: andre@0: prError = PR_BAD_DESCRIPTOR_ERROR; andre@0: break; andre@0: case ERROR_FILE_NOT_FOUND: andre@0: prError = PR_FILE_NOT_FOUND_ERROR; andre@0: break; andre@0: case ERROR_HANDLE_DISK_FULL: andre@0: prError = PR_NO_DEVICE_SPACE_ERROR; andre@0: break; andre@0: case ERROR_INVALID_ADDRESS: andre@0: prError = PR_ACCESS_FAULT_ERROR; andre@0: break; andre@0: case ERROR_INVALID_HANDLE: andre@0: prError = PR_BAD_DESCRIPTOR_ERROR; andre@0: break; andre@0: case ERROR_INVALID_NAME: andre@0: prError = PR_INVALID_ARGUMENT_ERROR; andre@0: break; andre@0: case ERROR_INVALID_PARAMETER: andre@0: prError = PR_INVALID_ARGUMENT_ERROR; andre@0: break; andre@0: case ERROR_INVALID_USER_BUFFER: andre@0: prError = PR_INSUFFICIENT_RESOURCES_ERROR; andre@0: break; andre@0: case ERROR_LOCKED: andre@0: prError = PR_FILE_IS_LOCKED_ERROR; andre@0: break; andre@0: case ERROR_NETNAME_DELETED: andre@0: prError = PR_CONNECT_RESET_ERROR; andre@0: break; andre@0: case ERROR_NOACCESS: andre@0: prError = PR_ACCESS_FAULT_ERROR; andre@0: break; andre@0: case ERROR_NOT_ENOUGH_MEMORY: andre@0: prError = PR_INSUFFICIENT_RESOURCES_ERROR; andre@0: break; andre@0: case ERROR_NOT_ENOUGH_QUOTA: andre@0: prError = PR_OUT_OF_MEMORY_ERROR; andre@0: break; andre@0: case ERROR_NOT_READY: andre@0: prError = PR_IO_ERROR; andre@0: break; andre@0: case ERROR_NO_MORE_FILES: andre@0: prError = PR_NO_MORE_FILES_ERROR; andre@0: break; andre@0: case ERROR_OPEN_FAILED: andre@0: prError = PR_IO_ERROR; andre@0: break; andre@0: case ERROR_OPEN_FILES: andre@0: prError = PR_IO_ERROR; andre@0: break; andre@0: case ERROR_OPERATION_ABORTED: andre@0: prError = PR_OPERATION_ABORTED_ERROR; andre@0: break; andre@0: case ERROR_OUTOFMEMORY: andre@0: prError = PR_INSUFFICIENT_RESOURCES_ERROR; andre@0: break; andre@0: case ERROR_PATH_BUSY: andre@0: prError = PR_IO_ERROR; andre@0: break; andre@0: case ERROR_PATH_NOT_FOUND: andre@0: prError = PR_FILE_NOT_FOUND_ERROR; andre@0: break; andre@0: case ERROR_SEEK_ON_DEVICE: andre@0: prError = PR_IO_ERROR; andre@0: break; andre@0: case ERROR_SHARING_VIOLATION: andre@0: prError = PR_FILE_IS_BUSY_ERROR; andre@0: break; andre@0: case ERROR_STACK_OVERFLOW: andre@0: prError = PR_ACCESS_FAULT_ERROR; andre@0: break; andre@0: case ERROR_TOO_MANY_OPEN_FILES: andre@0: prError = PR_SYS_DESC_TABLE_FULL_ERROR; andre@0: break; andre@0: case ERROR_WRITE_PROTECT: andre@0: prError = PR_NO_ACCESS_RIGHTS_ERROR; andre@0: break; andre@0: case WSAEACCES: andre@0: prError = PR_NO_ACCESS_RIGHTS_ERROR; andre@0: break; andre@0: case WSAEADDRINUSE: andre@0: prError = PR_ADDRESS_IN_USE_ERROR; andre@0: break; andre@0: case WSAEADDRNOTAVAIL: andre@0: prError = PR_ADDRESS_NOT_AVAILABLE_ERROR; andre@0: break; andre@0: case WSAEAFNOSUPPORT: andre@0: prError = PR_ADDRESS_NOT_SUPPORTED_ERROR; andre@0: break; andre@0: case WSAEALREADY: andre@0: prError = PR_ALREADY_INITIATED_ERROR; andre@0: break; andre@0: case WSAEBADF: andre@0: prError = PR_BAD_DESCRIPTOR_ERROR; andre@0: break; andre@0: case WSAECONNABORTED: andre@0: prError = PR_CONNECT_ABORTED_ERROR; andre@0: break; andre@0: case WSAECONNREFUSED: andre@0: prError = PR_CONNECT_REFUSED_ERROR; andre@0: break; andre@0: case WSAECONNRESET: andre@0: prError = PR_CONNECT_RESET_ERROR; andre@0: break; andre@0: case WSAEDESTADDRREQ: andre@0: prError = PR_INVALID_ARGUMENT_ERROR; andre@0: break; andre@0: case WSAEFAULT: andre@0: prError = PR_ACCESS_FAULT_ERROR; andre@0: break; andre@0: case WSAEHOSTUNREACH: andre@0: prError = PR_HOST_UNREACHABLE_ERROR; andre@0: break; andre@0: case WSAEINVAL: andre@0: prError = PR_INVALID_ARGUMENT_ERROR; andre@0: break; andre@0: case WSAEISCONN: andre@0: prError = PR_IS_CONNECTED_ERROR; andre@0: break; andre@0: case WSAEMFILE: andre@0: prError = PR_PROC_DESC_TABLE_FULL_ERROR; andre@0: break; andre@0: case WSAEMSGSIZE: andre@0: prError = PR_BUFFER_OVERFLOW_ERROR; andre@0: break; andre@0: case WSAENETDOWN: andre@0: prError = PR_NETWORK_DOWN_ERROR; andre@0: break; andre@0: case WSAENETRESET: andre@0: prError = PR_CONNECT_ABORTED_ERROR; andre@0: break; andre@0: case WSAENETUNREACH: andre@0: prError = PR_NETWORK_UNREACHABLE_ERROR; andre@0: break; andre@0: case WSAENOBUFS: andre@0: prError = PR_INSUFFICIENT_RESOURCES_ERROR; andre@0: break; andre@0: case WSAENOPROTOOPT: andre@0: prError = PR_INVALID_ARGUMENT_ERROR; andre@0: break; andre@0: case WSAENOTCONN: andre@0: prError = PR_NOT_CONNECTED_ERROR; andre@0: break; andre@0: case WSAENOTSOCK: andre@0: prError = PR_NOT_SOCKET_ERROR; andre@0: break; andre@0: case WSAEOPNOTSUPP: andre@0: prError = PR_OPERATION_NOT_SUPPORTED_ERROR; andre@0: break; andre@0: case WSAEPROTONOSUPPORT: andre@0: prError = PR_PROTOCOL_NOT_SUPPORTED_ERROR; andre@0: break; andre@0: case WSAEPROTOTYPE: andre@0: prError = PR_INVALID_ARGUMENT_ERROR; andre@0: break; andre@0: case WSAESHUTDOWN: andre@0: prError = PR_SOCKET_SHUTDOWN_ERROR; andre@0: break; andre@0: case WSAESOCKTNOSUPPORT: andre@0: prError = PR_INVALID_ARGUMENT_ERROR; andre@0: break; andre@0: case WSAETIMEDOUT: andre@0: prError = PR_CONNECT_ABORTED_ERROR; andre@0: break; andre@0: case WSAEWOULDBLOCK: andre@0: prError = PR_WOULD_BLOCK_ERROR; andre@0: break; andre@0: default: andre@0: prError = PR_UNKNOWN_ERROR; andre@0: break; andre@0: } andre@0: PR_SetError(prError, err); andre@0: } andre@0: andre@0: void _MD_win32_map_opendir_error(PRInt32 err) andre@0: { andre@0: _MD_win32_map_default_error(err); andre@0: } andre@0: andre@0: void _MD_win32_map_closedir_error(PRInt32 err) andre@0: { andre@0: _MD_win32_map_default_error(err); andre@0: } andre@0: andre@0: void _MD_unix_readdir_error(PRInt32 err) andre@0: { andre@0: _MD_win32_map_default_error(err); andre@0: } andre@0: andre@0: void _MD_win32_map_delete_error(PRInt32 err) andre@0: { andre@0: _MD_win32_map_default_error(err); andre@0: } andre@0: andre@0: /* The error code for stat() is in errno. */ andre@0: void _MD_win32_map_stat_error(PRInt32 err) andre@0: { andre@0: _MD_win32_map_default_errno(err); andre@0: } andre@0: andre@0: void _MD_win32_map_fstat_error(PRInt32 err) andre@0: { andre@0: _MD_win32_map_default_error(err); andre@0: } andre@0: andre@0: void _MD_win32_map_rename_error(PRInt32 err) andre@0: { andre@0: _MD_win32_map_default_error(err); andre@0: } andre@0: andre@0: /* The error code for access() is in errno. */ andre@0: void _MD_win32_map_access_error(PRInt32 err) andre@0: { andre@0: _MD_win32_map_default_errno(err); andre@0: } andre@0: andre@0: void _MD_win32_map_mkdir_error(PRInt32 err) andre@0: { andre@0: _MD_win32_map_default_error(err); andre@0: } andre@0: andre@0: void _MD_win32_map_rmdir_error(PRInt32 err) andre@0: { andre@0: _MD_win32_map_default_error(err); andre@0: } andre@0: andre@0: void _MD_win32_map_read_error(PRInt32 err) andre@0: { andre@0: _MD_win32_map_default_error(err); andre@0: } andre@0: andre@0: void _MD_win32_map_transmitfile_error(PRInt32 err) andre@0: { andre@0: _MD_win32_map_default_error(err); andre@0: } andre@0: andre@0: void _MD_win32_map_write_error(PRInt32 err) andre@0: { andre@0: _MD_win32_map_default_error(err); andre@0: } andre@0: andre@0: void _MD_win32_map_lseek_error(PRInt32 err) andre@0: { andre@0: _MD_win32_map_default_error(err); andre@0: } andre@0: andre@0: void _MD_win32_map_fsync_error(PRInt32 err) andre@0: { andre@0: _MD_win32_map_default_error(err); andre@0: } andre@0: andre@0: /* andre@0: * For both CloseHandle() and closesocket(). andre@0: */ andre@0: void _MD_win32_map_close_error(PRInt32 err) andre@0: { andre@0: _MD_win32_map_default_error(err); andre@0: } andre@0: andre@0: void _MD_win32_map_socket_error(PRInt32 err) andre@0: { andre@0: PR_ASSERT(err != WSANOTINITIALISED); andre@0: _MD_win32_map_default_error(err); andre@0: } andre@0: andre@0: void _MD_win32_map_recv_error(PRInt32 err) andre@0: { andre@0: _MD_win32_map_default_error(err); andre@0: } andre@0: andre@0: void _MD_win32_map_recvfrom_error(PRInt32 err) andre@0: { andre@0: _MD_win32_map_default_error(err); andre@0: } andre@0: andre@0: void _MD_win32_map_send_error(PRInt32 err) andre@0: { andre@0: PRErrorCode prError; andre@0: andre@0: switch (err) { andre@0: case WSAEMSGSIZE: andre@0: prError = PR_INVALID_ARGUMENT_ERROR; andre@0: break; andre@0: default: andre@0: _MD_win32_map_default_error(err); andre@0: return; andre@0: } andre@0: PR_SetError(prError, err); andre@0: } andre@0: andre@0: void _MD_win32_map_sendto_error(PRInt32 err) andre@0: { andre@0: PRErrorCode prError; andre@0: andre@0: switch (err) { andre@0: case WSAEMSGSIZE: andre@0: prError = PR_INVALID_ARGUMENT_ERROR; andre@0: break; andre@0: default: andre@0: _MD_win32_map_default_error(err); andre@0: return; andre@0: } andre@0: PR_SetError(prError, err); andre@0: } andre@0: andre@0: void _MD_win32_map_accept_error(PRInt32 err) andre@0: { andre@0: PRErrorCode prError; andre@0: andre@0: switch (err) { andre@0: case WSAEOPNOTSUPP: andre@0: prError = PR_NOT_TCP_SOCKET_ERROR; andre@0: break; andre@0: case WSAEINVAL: andre@0: prError = PR_INVALID_STATE_ERROR; andre@0: break; andre@0: default: andre@0: _MD_win32_map_default_error(err); andre@0: return; andre@0: } andre@0: PR_SetError(prError, err); andre@0: } andre@0: andre@0: void _MD_win32_map_acceptex_error(PRInt32 err) andre@0: { andre@0: _MD_win32_map_default_error(err); andre@0: } andre@0: andre@0: void _MD_win32_map_connect_error(PRInt32 err) andre@0: { andre@0: PRErrorCode prError; andre@0: andre@0: switch (err) { andre@0: case WSAEWOULDBLOCK: andre@0: prError = PR_IN_PROGRESS_ERROR; andre@0: break; andre@0: case WSAEINVAL: andre@0: prError = PR_ALREADY_INITIATED_ERROR; andre@0: break; andre@0: case WSAETIMEDOUT: andre@0: prError = PR_IO_TIMEOUT_ERROR; andre@0: break; andre@0: default: andre@0: _MD_win32_map_default_error(err); andre@0: return; andre@0: } andre@0: PR_SetError(prError, err); andre@0: } andre@0: andre@0: void _MD_win32_map_bind_error(PRInt32 err) andre@0: { andre@0: PRErrorCode prError; andre@0: andre@0: switch (err) { andre@0: case WSAEINVAL: andre@0: prError = PR_SOCKET_ADDRESS_IS_BOUND_ERROR; andre@0: break; andre@0: default: andre@0: _MD_win32_map_default_error(err); andre@0: return; andre@0: } andre@0: PR_SetError(prError, err); andre@0: } andre@0: andre@0: void _MD_win32_map_listen_error(PRInt32 err) andre@0: { andre@0: PRErrorCode prError; andre@0: andre@0: switch (err) { andre@0: case WSAEOPNOTSUPP: andre@0: prError = PR_NOT_TCP_SOCKET_ERROR; andre@0: break; andre@0: case WSAEINVAL: andre@0: prError = PR_INVALID_STATE_ERROR; andre@0: break; andre@0: default: andre@0: _MD_win32_map_default_error(err); andre@0: return; andre@0: } andre@0: PR_SetError(prError, err); andre@0: } andre@0: andre@0: void _MD_win32_map_shutdown_error(PRInt32 err) andre@0: { andre@0: _MD_win32_map_default_error(err); andre@0: } andre@0: andre@0: void _MD_win32_map_getsockname_error(PRInt32 err) andre@0: { andre@0: PRErrorCode prError; andre@0: andre@0: switch (err) { andre@0: case WSAEINVAL: andre@0: prError = PR_INVALID_STATE_ERROR; andre@0: break; andre@0: default: andre@0: _MD_win32_map_default_error(err); andre@0: return; andre@0: } andre@0: PR_SetError(prError, err); andre@0: } andre@0: andre@0: void _MD_win32_map_getpeername_error(PRInt32 err) andre@0: { andre@0: _MD_win32_map_default_error(err); andre@0: } andre@0: andre@0: void _MD_win32_map_getsockopt_error(PRInt32 err) andre@0: { andre@0: _MD_win32_map_default_error(err); andre@0: } andre@0: andre@0: void _MD_win32_map_setsockopt_error(PRInt32 err) andre@0: { andre@0: _MD_win32_map_default_error(err); andre@0: } andre@0: andre@0: void _MD_win32_map_open_error(PRInt32 err) andre@0: { andre@0: _MD_win32_map_default_error(err); andre@0: } andre@0: andre@0: void _MD_win32_map_gethostname_error(PRInt32 err) andre@0: { andre@0: _MD_win32_map_default_error(err); andre@0: } andre@0: andre@0: /* Win32 select() only works on sockets. So in this andre@0: ** context, WSAENOTSOCK is equivalent to EBADF on Unix. andre@0: */ andre@0: void _MD_win32_map_select_error(PRInt32 err) andre@0: { andre@0: PRErrorCode prError; andre@0: andre@0: switch (err) { andre@0: case WSAENOTSOCK: andre@0: prError = PR_BAD_DESCRIPTOR_ERROR; andre@0: break; andre@0: default: andre@0: _MD_win32_map_default_error(err); andre@0: return; andre@0: } andre@0: PR_SetError(prError, err); andre@0: } andre@0: andre@0: void _MD_win32_map_lockf_error(PRInt32 err) andre@0: { andre@0: _MD_win32_map_default_error(err); andre@0: }