| ... | @@ -2750,6 +2750,13 @@ pub const BindError = error{ | ... | @@ -2750,6 +2750,13 @@ pub const BindError = error{ |
| 2750 | | 2750 | |
| 2751 | /// The socket inode would reside on a read-only filesystem. | 2751 | /// The socket inode would reside on a read-only filesystem. |
| 2752 | ReadOnlyFileSystem, | 2752 | ReadOnlyFileSystem, |
| | 2753 | |
| | 2754 | /// The network subsystem has failed. |
| | 2755 | NetworkSubsystemFailed, |
| | 2756 | |
| | 2757 | FileDescriptorNotASocket, |
| | 2758 | |
| | 2759 | AlreadyBound, |
| 2753 | } || UnexpectedError; | 2760 | } || UnexpectedError; |
| 2754 | | 2761 | |
| 2755 | /// addr is `*const T` where T is one of the sockaddr | 2762 | /// addr is `*const T` where T is one of the sockaddr |
| ... | @@ -2758,7 +2765,15 @@ pub fn bind(sock: socket_t, addr: *const sockaddr, len: socklen_t) BindError!voi | ... | @@ -2758,7 +2765,15 @@ pub fn bind(sock: socket_t, addr: *const sockaddr, len: socklen_t) BindError!voi |
| 2758 | if (builtin.os.tag == .windows) { | 2765 | if (builtin.os.tag == .windows) { |
| 2759 | if (rc == windows.ws2_32.SOCKET_ERROR) { | 2766 | if (rc == windows.ws2_32.SOCKET_ERROR) { |
| 2760 | switch (windows.ws2_32.WSAGetLastError()) { | 2767 | switch (windows.ws2_32.WSAGetLastError()) { |
| 2761 | // TODO: handle errors | 2768 | .WSANOTINITIALISED => unreachable, // not initialized WSA |
| | 2769 | .WSAEACCES => return error.AccessDenied, |
| | 2770 | .WSAEADDRINUSE => return error.AddressInUse, |
| | 2771 | .WSAEADDRNOTAVAIL => return error.AddressNotAvailable, |
| | 2772 | .WSAENOTSOCK => return error.FileDescriptorNotASocket, |
| | 2773 | .WSAEFAULT => unreachable, // invalid pointers |
| | 2774 | .WSAEINVAL => return error.AlreadyBound, |
| | 2775 | .WSAENOBUFS => return error.SystemResources, |
| | 2776 | .WSAENETDOWN => return error.NetworkSubsystemFailed, |
| 2762 | else => |err| return windows.unexpectedWSAError(err), | 2777 | else => |err| return windows.unexpectedWSAError(err), |
| 2763 | } | 2778 | } |
| 2764 | unreachable; | 2779 | unreachable; |
| ... | @@ -2799,6 +2814,19 @@ const ListenError = error{ | ... | @@ -2799,6 +2814,19 @@ const ListenError = error{ |
| 2799 | | 2814 | |
| 2800 | /// The socket is not of a type that supports the listen() operation. | 2815 | /// The socket is not of a type that supports the listen() operation. |
| 2801 | OperationNotSupported, | 2816 | OperationNotSupported, |
| | 2817 | |
| | 2818 | /// The network subsystem has failed. |
| | 2819 | NetworkSubsystemFailed, |
| | 2820 | |
| | 2821 | /// Ran out of system resources |
| | 2822 | /// On Windows it can either run out of socket descriptors or buffer space |
| | 2823 | SystemResources, |
| | 2824 | |
| | 2825 | /// Already connected |
| | 2826 | AlreadyConnected, |
| | 2827 | |
| | 2828 | /// Socket has not been bound yet |
| | 2829 | SocketNotBound, |
| 2802 | } || UnexpectedError; | 2830 | } || UnexpectedError; |
| 2803 | | 2831 | |
| 2804 | pub fn listen(sock: socket_t, backlog: u31) ListenError!void { | 2832 | pub fn listen(sock: socket_t, backlog: u31) ListenError!void { |
| ... | @@ -2806,7 +2834,15 @@ pub fn listen(sock: socket_t, backlog: u31) ListenError!void { | ... | @@ -2806,7 +2834,15 @@ pub fn listen(sock: socket_t, backlog: u31) ListenError!void { |
| 2806 | if (builtin.os.tag == .windows) { | 2834 | if (builtin.os.tag == .windows) { |
| 2807 | if (rc == windows.ws2_32.SOCKET_ERROR) { | 2835 | if (rc == windows.ws2_32.SOCKET_ERROR) { |
| 2808 | switch (windows.ws2_32.WSAGetLastError()) { | 2836 | switch (windows.ws2_32.WSAGetLastError()) { |
| 2809 | // TODO: handle errors | 2837 | .WSANOTINITIALISED => unreachable, // not initialized WSA |
| | 2838 | .WSAENETDOWN => return error.NetworkSubsystemFailed, |
| | 2839 | .WSAEADDRINUSE => return error.AddressInUse, |
| | 2840 | .WSAEISCONN => return error.AlreadyConnected, |
| | 2841 | .WSAEINVAL => return error.SocketNotBound, |
| | 2842 | .WSAEMFILE, .WSAENOBUFS => return error.SystemResources, |
| | 2843 | .WSAENOTSOCK => return error.FileDescriptorNotASocket, |
| | 2844 | .WSAEOPNOTSUPP => return error.OperationNotSupported, |
| | 2845 | .WSAEINPROGRESS => unreachable, |
| 2810 | else => |err| return windows.unexpectedWSAError(err), | 2846 | else => |err| return windows.unexpectedWSAError(err), |
| 2811 | } | 2847 | } |
| 2812 | } | 2848 | } |
| ... | @@ -2826,6 +2862,9 @@ pub fn listen(sock: socket_t, backlog: u31) ListenError!void { | ... | @@ -2826,6 +2862,9 @@ pub fn listen(sock: socket_t, backlog: u31) ListenError!void { |
| 2826 | pub const AcceptError = error{ | 2862 | pub const AcceptError = error{ |
| 2827 | ConnectionAborted, | 2863 | ConnectionAborted, |
| 2828 | | 2864 | |
| | 2865 | /// The file descriptor sockfd does not refer to a socket. |
| | 2866 | FileDescriptorNotASocket, |
| | 2867 | |
| 2829 | /// The per-process limit on the number of open file descriptors has been reached. | 2868 | /// The per-process limit on the number of open file descriptors has been reached. |
| 2830 | ProcessFdQuotaExceeded, | 2869 | ProcessFdQuotaExceeded, |
| 2831 | | 2870 | |
| ... | @@ -2851,6 +2890,16 @@ pub const AcceptError = error{ | ... | @@ -2851,6 +2890,16 @@ pub const AcceptError = error{ |
| 2851 | /// Permission to create a socket of the specified type and/or | 2890 | /// Permission to create a socket of the specified type and/or |
| 2852 | /// protocol is denied. | 2891 | /// protocol is denied. |
| 2853 | PermissionDenied, | 2892 | PermissionDenied, |
| | 2893 | |
| | 2894 | /// An incoming connection was indicated, but was subsequently terminated by the |
| | 2895 | /// remote peer prior to accepting the call. |
| | 2896 | ConnectionResetByPeer, |
| | 2897 | |
| | 2898 | /// The network subsystem has failed. |
| | 2899 | NetworkSubsystemFailed, |
| | 2900 | |
| | 2901 | /// The referenced socket is not a type that supports connection-oriented service. |
| | 2902 | OperationNotSupported, |
| 2854 | } || UnexpectedError; | 2903 | } || UnexpectedError; |
| 2855 | | 2904 | |
| 2856 | /// Accept a connection on a socket. | 2905 | /// Accept a connection on a socket. |
| ... | @@ -2892,7 +2941,15 @@ pub fn accept( | ... | @@ -2892,7 +2941,15 @@ pub fn accept( |
| 2892 | if (builtin.os.tag == .windows) { | 2941 | if (builtin.os.tag == .windows) { |
| 2893 | if (rc == windows.ws2_32.INVALID_SOCKET) { | 2942 | if (rc == windows.ws2_32.INVALID_SOCKET) { |
| 2894 | switch (windows.ws2_32.WSAGetLastError()) { | 2943 | switch (windows.ws2_32.WSAGetLastError()) { |
| 2895 | // TODO: handle errors | 2944 | .WSANOTINITIALISED => unreachable, // not initialized WSA |
| | 2945 | .WSAECONNRESET => return error.ConnectionResetByPeer, |
| | 2946 | .WSAEFAULT => unreachable, |
| | 2947 | .WSAEINVAL => return error.SocketNotListening, |
| | 2948 | .WSAEMFILE => return error.ProcessFdQuotaExceeded, |
| | 2949 | .WSAENETDOWN => return error.NetworkSubsystemFailed, |
| | 2950 | .WSAENOBUFS => return error.FileDescriptorNotASocket, |
| | 2951 | .WSAEOPNOTSUPP => return error.OperationNotSupported, |
| | 2952 | .WSAEWOULDBLOCK => return error.WouldBlock, |
| 2896 | else => |err| return windows.unexpectedWSAError(err), | 2953 | else => |err| return windows.unexpectedWSAError(err), |
| 2897 | } | 2954 | } |
| 2898 | } else { | 2955 | } else { |
| ... | @@ -3044,6 +3101,14 @@ pub fn eventfd(initval: u32, flags: u32) EventFdError!i32 { | ... | @@ -3044,6 +3101,14 @@ pub fn eventfd(initval: u32, flags: u32) EventFdError!i32 { |
| 3044 | pub const GetSockNameError = error{ | 3101 | pub const GetSockNameError = error{ |
| 3045 | /// Insufficient resources were available in the system to perform the operation. | 3102 | /// Insufficient resources were available in the system to perform the operation. |
| 3046 | SystemResources, | 3103 | SystemResources, |
| | 3104 | |
| | 3105 | /// The network subsystem has failed. |
| | 3106 | NetworkSubsystemFailed, |
| | 3107 | |
| | 3108 | /// Socket hasn't been bound yet |
| | 3109 | SocketNotBound, |
| | 3110 | |
| | 3111 | FileDescriptorNotASocket, |
| 3047 | } || UnexpectedError; | 3112 | } || UnexpectedError; |
| 3048 | | 3113 | |
| 3049 | pub fn getsockname(sock: socket_t, addr: *sockaddr, addrlen: *socklen_t) GetSockNameError!void { | 3114 | pub fn getsockname(sock: socket_t, addr: *sockaddr, addrlen: *socklen_t) GetSockNameError!void { |
| ... | @@ -3051,7 +3116,11 @@ pub fn getsockname(sock: socket_t, addr: *sockaddr, addrlen: *socklen_t) GetSock | ... | @@ -3051,7 +3116,11 @@ pub fn getsockname(sock: socket_t, addr: *sockaddr, addrlen: *socklen_t) GetSock |
| 3051 | if (builtin.os.tag == .windows) { | 3116 | if (builtin.os.tag == .windows) { |
| 3052 | if (rc == windows.ws2_32.SOCKET_ERROR) { | 3117 | if (rc == windows.ws2_32.SOCKET_ERROR) { |
| 3053 | switch (windows.ws2_32.WSAGetLastError()) { | 3118 | switch (windows.ws2_32.WSAGetLastError()) { |
| 3054 | // TODO: handle errors | 3119 | .WSANOTINITIALISED => unreachable, |
| | 3120 | .WSAENETDOWN => return error.NetworkSubsystemFailed, |
| | 3121 | .WSAEFAULT => unreachable, // addr or addrlen have invalid pointers or addrlen points to an incorrect value |
| | 3122 | .WSAENOTSOCK => return error.FileDescriptorNotASocket, |
| | 3123 | .WSAEINVAL => return error.SocketNotBound, |
| 3055 | else => |err| return windows.unexpectedWSAError(err), | 3124 | else => |err| return windows.unexpectedWSAError(err), |
| 3056 | } | 3125 | } |
| 3057 | } | 3126 | } |
| ... | @@ -3064,7 +3133,7 @@ pub fn getsockname(sock: socket_t, addr: *sockaddr, addrlen: *socklen_t) GetSock | ... | @@ -3064,7 +3133,7 @@ pub fn getsockname(sock: socket_t, addr: *sockaddr, addrlen: *socklen_t) GetSock |
| 3064 | EBADF => unreachable, // always a race condition | 3133 | EBADF => unreachable, // always a race condition |
| 3065 | EFAULT => unreachable, | 3134 | EFAULT => unreachable, |
| 3066 | EINVAL => unreachable, // invalid parameters | 3135 | EINVAL => unreachable, // invalid parameters |
| 3067 | ENOTSOCK => unreachable, | 3136 | ENOTSOCK => return error.FileDescriptorNotASocket, |
| 3068 | ENOBUFS => return error.SystemResources, | 3137 | ENOBUFS => return error.SystemResources, |
| 3069 | } | 3138 | } |
| 3070 | } | 3139 | } |
| ... | @@ -4011,7 +4080,10 @@ fn setSockFlags(sock: socket_t, flags: u32) !void { | ... | @@ -4011,7 +4080,10 @@ fn setSockFlags(sock: socket_t, flags: u32) !void { |
| 4011 | var mode: c_ulong = 1; | 4080 | var mode: c_ulong = 1; |
| 4012 | if (windows.ws2_32.ioctlsocket(sock, windows.ws2_32.FIONBIO, &mode) == windows.ws2_32.SOCKET_ERROR) { | 4081 | if (windows.ws2_32.ioctlsocket(sock, windows.ws2_32.FIONBIO, &mode) == windows.ws2_32.SOCKET_ERROR) { |
| 4013 | switch (windows.ws2_32.WSAGetLastError()) { | 4082 | switch (windows.ws2_32.WSAGetLastError()) { |
| 4014 | // TODO: handle errors | 4083 | .WSANOTINITIALISED => unreachable, |
| | 4084 | .WSAENETDOWN => return error.NetworkSubsystemFailed, |
| | 4085 | .WSAENOTSOCK => return error.FileDescriptorNotASocket, |
| | 4086 | // TODO: handle more errors |
| 4015 | else => |err| return windows.unexpectedWSAError(err), | 4087 | else => |err| return windows.unexpectedWSAError(err), |
| 4016 | } | 4088 | } |
| 4017 | } | 4089 | } |
| ... | @@ -4625,6 +4697,8 @@ pub const SendError = error{ | ... | @@ -4625,6 +4697,8 @@ pub const SendError = error{ |
| 4625 | /// The local end has been shut down on a connection oriented socket. In this case, the | 4697 | /// The local end has been shut down on a connection oriented socket. In this case, the |
| 4626 | /// process will also receive a SIGPIPE unless MSG_NOSIGNAL is set. | 4698 | /// process will also receive a SIGPIPE unless MSG_NOSIGNAL is set. |
| 4627 | BrokenPipe, | 4699 | BrokenPipe, |
| | 4700 | |
| | 4701 | FileDescriptorNotASocket, |
| 4628 | } || UnexpectedError; | 4702 | } || UnexpectedError; |
| 4629 | | 4703 | |
| 4630 | /// Transmit a message to another socket. | 4704 | /// Transmit a message to another socket. |
| ... | @@ -4666,7 +4740,12 @@ pub fn sendto( | ... | @@ -4666,7 +4740,12 @@ pub fn sendto( |
| 4666 | if (builtin.os.tag == .windows) { | 4740 | if (builtin.os.tag == .windows) { |
| 4667 | if (rc == windows.ws2_32.SOCKET_ERROR) { | 4741 | if (rc == windows.ws2_32.SOCKET_ERROR) { |
| 4668 | switch (windows.ws2_32.WSAGetLastError()) { | 4742 | switch (windows.ws2_32.WSAGetLastError()) { |
| 4669 | // TODO: handle errors | 4743 | .WSAEACCES => return error.AccessDenied, |
| | 4744 | .WSAECONNRESET => return error.ConnectionResetByPeer, |
| | 4745 | .WSAEMSGSIZE => return error.MessageTooBig, |
| | 4746 | .WSAENOBUFS => return error.SystemResources, |
| | 4747 | .WSAENOTSOCK => return error.FileDescriptorNotASocket, |
| | 4748 | // TODO: handle more errors |
| 4670 | else => |err| return windows.unexpectedWSAError(err), | 4749 | else => |err| return windows.unexpectedWSAError(err), |
| 4671 | } | 4750 | } |
| 4672 | } else { | 4751 | } else { |
| ... | @@ -5158,6 +5237,20 @@ pub const RecvFromError = error{ | ... | @@ -5158,6 +5237,20 @@ pub const RecvFromError = error{ |
| 5158 | | 5237 | |
| 5159 | /// Could not allocate kernel memory. | 5238 | /// Could not allocate kernel memory. |
| 5160 | SystemResources, | 5239 | SystemResources, |
| | 5240 | |
| | 5241 | ConnectionResetByPeer, |
| | 5242 | |
| | 5243 | /// The socket has not been bound. |
| | 5244 | SocketNotBound, |
| | 5245 | |
| | 5246 | /// The UDP message was too big for the buffer and part of it has been discarded |
| | 5247 | MessageTooBig, |
| | 5248 | |
| | 5249 | /// The network subsystem has failed. |
| | 5250 | NetworkSubsystemFailed, |
| | 5251 | |
| | 5252 | /// The socket is not connected (connection-oriented sockets only). |
| | 5253 | SocketNotConnected, |
| 5161 | } || UnexpectedError; | 5254 | } || UnexpectedError; |
| 5162 | | 5255 | |
| 5163 | pub fn recv(sock: socket_t, buf: []u8, flags: u32) RecvFromError!usize { | 5256 | pub fn recv(sock: socket_t, buf: []u8, flags: u32) RecvFromError!usize { |
| ... | @@ -5176,7 +5269,14 @@ pub fn recvfrom( | ... | @@ -5176,7 +5269,14 @@ pub fn recvfrom( |
| 5176 | if (builtin.os.tag == .windows) { | 5269 | if (builtin.os.tag == .windows) { |
| 5177 | if (rc == windows.ws2_32.SOCKET_ERROR) { | 5270 | if (rc == windows.ws2_32.SOCKET_ERROR) { |
| 5178 | switch (windows.ws2_32.WSAGetLastError()) { | 5271 | switch (windows.ws2_32.WSAGetLastError()) { |
| 5179 | // TODO: handle errors | 5272 | .WSANOTINITIALISED => unreachable, |
| | 5273 | .WSAECONNRESET => return error.ConnectionResetByPeer, |
| | 5274 | .WSAEINVAL => return error.SocketNotBound, |
| | 5275 | .WSAEMSGSIZE => return error.MessageTooBig, |
| | 5276 | .WSAENETDOWN => return error.NetworkSubsystemFailed, |
| | 5277 | .WSAENOTCONN => return error.SocketNotConnected, |
| | 5278 | .WSAEWOULDBLOCK => return error.WouldBlock, |
| | 5279 | // TODO: handle more errors |
| 5180 | else => |err| return windows.unexpectedWSAError(err), | 5280 | else => |err| return windows.unexpectedWSAError(err), |
| 5181 | } | 5281 | } |
| 5182 | } else { | 5282 | } else { |