Commit dfe3440540

Andrew Kelley <andrew@ziglang.org>
2023-04-09 17:38:38
std.os.sendto: use ws2_32 on Windows
closes #9971
1 parent 95ac94b
Changed files (1)
lib
std
lib/std/os.zig
@@ -5913,66 +5913,64 @@ pub fn sendto(
     dest_addr: ?*const sockaddr,
     addrlen: socklen_t,
 ) SendToError!usize {
+    if (builtin.os.tag == .windows) {
+        switch (windows.ws2_32.sendto(sockfd, buf.ptr, buf.len, flags, dest_addr, addrlen)) {
+            windows.ws2_32.SOCKET_ERROR => switch (windows.ws2_32.WSAGetLastError()) {
+                .WSAEACCES => return error.AccessDenied,
+                .WSAEADDRNOTAVAIL => return error.AddressNotAvailable,
+                .WSAECONNRESET => return error.ConnectionResetByPeer,
+                .WSAEMSGSIZE => return error.MessageTooBig,
+                .WSAENOBUFS => return error.SystemResources,
+                .WSAENOTSOCK => return error.FileDescriptorNotASocket,
+                .WSAEAFNOSUPPORT => return error.AddressFamilyNotSupported,
+                .WSAEDESTADDRREQ => unreachable, // A destination address is required.
+                .WSAEFAULT => unreachable, // The lpBuffers, lpTo, lpOverlapped, lpNumberOfBytesSent, or lpCompletionRoutine parameters are not part of the user address space, or the lpTo parameter is too small.
+                .WSAEHOSTUNREACH => return error.NetworkUnreachable,
+                // TODO: WSAEINPROGRESS, WSAEINTR
+                .WSAEINVAL => unreachable,
+                .WSAENETDOWN => return error.NetworkSubsystemFailed,
+                .WSAENETRESET => return error.ConnectionResetByPeer,
+                .WSAENETUNREACH => return error.NetworkUnreachable,
+                .WSAENOTCONN => return error.SocketNotConnected,
+                .WSAESHUTDOWN => unreachable, // The socket has been shut down; it is not possible to WSASendTo on a socket after shutdown has been invoked with how set to SD_SEND or SD_BOTH.
+                .WSAEWOULDBLOCK => return error.WouldBlock,
+                .WSANOTINITIALISED => unreachable, // A successful WSAStartup call must occur before using this function.
+                else => |err| return windows.unexpectedWSAError(err),
+            },
+            else => |rc| return @intCast(usize, rc),
+        }
+    }
     while (true) {
         const rc = system.sendto(sockfd, buf.ptr, buf.len, flags, dest_addr, addrlen);
-        if (builtin.os.tag == .windows) {
-            if (rc == windows.ws2_32.SOCKET_ERROR) {
-                switch (windows.ws2_32.WSAGetLastError()) {
-                    .WSAEACCES => return error.AccessDenied,
-                    .WSAEADDRNOTAVAIL => return error.AddressNotAvailable,
-                    .WSAECONNRESET => return error.ConnectionResetByPeer,
-                    .WSAEMSGSIZE => return error.MessageTooBig,
-                    .WSAENOBUFS => return error.SystemResources,
-                    .WSAENOTSOCK => return error.FileDescriptorNotASocket,
-                    .WSAEAFNOSUPPORT => return error.AddressFamilyNotSupported,
-                    .WSAEDESTADDRREQ => unreachable, // A destination address is required.
-                    .WSAEFAULT => unreachable, // The lpBuffers, lpTo, lpOverlapped, lpNumberOfBytesSent, or lpCompletionRoutine parameters are not part of the user address space, or the lpTo parameter is too small.
-                    .WSAEHOSTUNREACH => return error.NetworkUnreachable,
-                    // TODO: WSAEINPROGRESS, WSAEINTR
-                    .WSAEINVAL => unreachable,
-                    .WSAENETDOWN => return error.NetworkSubsystemFailed,
-                    .WSAENETRESET => return error.ConnectionResetByPeer,
-                    .WSAENETUNREACH => return error.NetworkUnreachable,
-                    .WSAENOTCONN => return error.SocketNotConnected,
-                    .WSAESHUTDOWN => unreachable, // The socket has been shut down; it is not possible to WSASendTo on a socket after shutdown has been invoked with how set to SD_SEND or SD_BOTH.
-                    .WSAEWOULDBLOCK => return error.WouldBlock,
-                    .WSANOTINITIALISED => unreachable, // A successful WSAStartup call must occur before using this function.
-                    else => |err| return windows.unexpectedWSAError(err),
-                }
-            } else {
-                return @intCast(usize, rc);
-            }
-        } else {
-            switch (errno(rc)) {
-                .SUCCESS => return @intCast(usize, rc),
+        switch (errno(rc)) {
+            .SUCCESS => return @intCast(usize, rc),
 
-                .ACCES => return error.AccessDenied,
-                .AGAIN => return error.WouldBlock,
-                .ALREADY => return error.FastOpenAlreadyInProgress,
-                .BADF => unreachable, // always a race condition
-                .CONNRESET => return error.ConnectionResetByPeer,
-                .DESTADDRREQ => unreachable, // The socket is not connection-mode, and no peer address is set.
-                .FAULT => unreachable, // An invalid user space address was specified for an argument.
-                .INTR => continue,
-                .INVAL => return error.UnreachableAddress,
-                .ISCONN => unreachable, // connection-mode socket was connected already but a recipient was specified
-                .MSGSIZE => return error.MessageTooBig,
-                .NOBUFS => return error.SystemResources,
-                .NOMEM => return error.SystemResources,
-                .NOTSOCK => unreachable, // The file descriptor sockfd does not refer to a socket.
-                .OPNOTSUPP => unreachable, // Some bit in the flags argument is inappropriate for the socket type.
-                .PIPE => return error.BrokenPipe,
-                .AFNOSUPPORT => return error.AddressFamilyNotSupported,
-                .LOOP => return error.SymLinkLoop,
-                .NAMETOOLONG => return error.NameTooLong,
-                .NOENT => return error.FileNotFound,
-                .NOTDIR => return error.NotDir,
-                .HOSTUNREACH => return error.NetworkUnreachable,
-                .NETUNREACH => return error.NetworkUnreachable,
-                .NOTCONN => return error.SocketNotConnected,
-                .NETDOWN => return error.NetworkSubsystemFailed,
-                else => |err| return unexpectedErrno(err),
-            }
+            .ACCES => return error.AccessDenied,
+            .AGAIN => return error.WouldBlock,
+            .ALREADY => return error.FastOpenAlreadyInProgress,
+            .BADF => unreachable, // always a race condition
+            .CONNRESET => return error.ConnectionResetByPeer,
+            .DESTADDRREQ => unreachable, // The socket is not connection-mode, and no peer address is set.
+            .FAULT => unreachable, // An invalid user space address was specified for an argument.
+            .INTR => continue,
+            .INVAL => return error.UnreachableAddress,
+            .ISCONN => unreachable, // connection-mode socket was connected already but a recipient was specified
+            .MSGSIZE => return error.MessageTooBig,
+            .NOBUFS => return error.SystemResources,
+            .NOMEM => return error.SystemResources,
+            .NOTSOCK => unreachable, // The file descriptor sockfd does not refer to a socket.
+            .OPNOTSUPP => unreachable, // Some bit in the flags argument is inappropriate for the socket type.
+            .PIPE => return error.BrokenPipe,
+            .AFNOSUPPORT => return error.AddressFamilyNotSupported,
+            .LOOP => return error.SymLinkLoop,
+            .NAMETOOLONG => return error.NameTooLong,
+            .NOENT => return error.FileNotFound,
+            .NOTDIR => return error.NotDir,
+            .HOSTUNREACH => return error.NetworkUnreachable,
+            .NETUNREACH => return error.NetworkUnreachable,
+            .NOTCONN => return error.SocketNotConnected,
+            .NETDOWN => return error.NetworkSubsystemFailed,
+            else => |err| return unexpectedErrno(err),
         }
     }
 }