authorgravatar for BarabasGitHub@users.noreply.github.comBas van den Berg <BarabasGitHub@users.noreply.github.com> 2020-09-09 18:55:45+02:00
committergravatar for BarabasGitHub@users.noreply.github.comBas van den Berg <BarabasGitHub@users.noreply.github.com> 2020-09-09 18:55:45+02:00
logf5b9e445aa9d2b344b87d4868f9fbb8021577f55
tree126838ce428230cea6cde16349515a7bd1317952
parent44f877d18bef6c82d727efeb5ff78ea97d3307bf

Handle some WSA errors


1 files changed, 108 insertions(+), 8 deletions(-)

lib/std/os.zig+108-8
...@@ -2750,6 +2750,13 @@ pub const BindError = error{...@@ -2750,6 +2750,13 @@ pub const BindError = error{
27502750
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;
27542761
2755/// addr is `*const T` where T is one of the sockaddr2762/// 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 errors2768 .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{
27992814
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;
28032831
2804pub fn listen(sock: socket_t, backlog: u31) ListenError!void {2832pub 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 errors2837 .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 {
2826pub const AcceptError = error{2862pub const AcceptError = error{
2827 ConnectionAborted,2863 ConnectionAborted,
28282864
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,
28312870
...@@ -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/or2890 /// 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;
28552904
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 errors2944 .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 {
3044pub const GetSockNameError = error{3101pub 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;
30483113
3049pub fn getsockname(sock: socket_t, addr: *sockaddr, addrlen: *socklen_t) GetSockNameError!void {3114pub 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 errors3119 .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 condition3133 EBADF => unreachable, // always a race condition
3065 EFAULT => unreachable,3134 EFAULT => unreachable,
3066 EINVAL => unreachable, // invalid parameters3135 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 errors4083 .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, the4697 /// 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;
46294703
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 errors4743 .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{
51585237
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;
51625255
5163pub fn recv(sock: socket_t, buf: []u8, flags: u32) RecvFromError!usize {5256pub 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 errors5272 .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 {