| ... | ... | @@ -13072,11 +13072,76 @@ fn netSendWindows( |
| 13072 | 13072 | ) struct { ?net.Socket.SendError, usize } { |
| 13073 | 13073 | if (!have_networking) return .{ error.NetworkDown, 0 }; |
| 13074 | 13074 | const t: *Threaded = @ptrCast(@alignCast(userdata)); |
| 13075 | | _ = t; |
| 13076 | | _ = handle; |
| 13077 | | _ = messages; |
| 13078 | | _ = flags; |
| 13079 | | @panic("TODO netSendWindows"); |
| 13075 | |
| 13076 | // Ignored flags: confirm, eor, fastopen |
| 13077 | const windows_flags: u32 = |
| 13078 | @as(u32, if (flags.oob) ws2_32.MSG.OOB else 0) | |
| 13079 | @as(u32, if (flags.dont_route) ws2_32.MSG.DONTROUTE else 0); |
| 13080 | |
| 13081 | for (messages, 0..) |*m, i| { |
| 13082 | netSendWindowsOne(t, handle, m, windows_flags) catch |err| return .{ err, i }; |
| 13083 | } |
| 13084 | return .{ null, messages.len }; |
| 13085 | } |
| 13086 | |
| 13087 | fn netSendWindowsOne( |
| 13088 | t: *Threaded, |
| 13089 | handle: net.Socket.Handle, |
| 13090 | message: *net.OutgoingMessage, |
| 13091 | flags: u32, |
| 13092 | ) net.Socket.SendError!void { |
| 13093 | var buf: ws2_32.WSABUF = .{ |
| 13094 | .buf = @constCast(message.data_ptr), |
| 13095 | .len = std.math.cast(u32, message.data_len) orelse return error.MessageOversize, |
| 13096 | }; |
| 13097 | var n: u32 = undefined; |
| 13098 | var address: WsaAddress = undefined; |
| 13099 | const address_size = addressToWsa(message.address, &address); |
| 13100 | var syscall: Syscall = try .start(); |
| 13101 | while (true) { |
| 13102 | const rc = ws2_32.WSASendTo( |
| 13103 | handle, |
| 13104 | (&buf)[0..1], |
| 13105 | 1, |
| 13106 | &n, |
| 13107 | flags, |
| 13108 | &address.any, |
| 13109 | address_size, |
| 13110 | null, |
| 13111 | null, |
| 13112 | ); |
| 13113 | if (rc != ws2_32.SOCKET_ERROR) { |
| 13114 | syscall.finish(); |
| 13115 | return; |
| 13116 | } |
| 13117 | switch (ws2_32.WSAGetLastError()) { |
| 13118 | .EINTR, .ECANCELLED, .E_CANCELLED, .OPERATION_ABORTED => { |
| 13119 | try syscall.checkCancel(); |
| 13120 | continue; |
| 13121 | }, |
| 13122 | .NOTINITIALISED => { |
| 13123 | syscall.finish(); |
| 13124 | try initializeWsa(t); |
| 13125 | syscall = try .start(); |
| 13126 | continue; |
| 13127 | }, |
| 13128 | |
| 13129 | .ECONNRESET => return syscall.fail(error.ConnectionResetByPeer), |
| 13130 | .ENETDOWN => return syscall.fail(error.NetworkDown), |
| 13131 | .ENETRESET => return syscall.fail(error.ConnectionResetByPeer), |
| 13132 | .ENOTCONN => return syscall.fail(error.SocketUnconnected), |
| 13133 | .EFAULT => unreachable, // a pointer is not completely contained in user address space. |
| 13134 | |
| 13135 | else => |err| { |
| 13136 | syscall.finish(); |
| 13137 | switch (err) { |
| 13138 | .EINVAL => return wsaErrorBug(err), |
| 13139 | .EMSGSIZE => return wsaErrorBug(err), |
| 13140 | else => return windows.unexpectedWSAError(err), |
| 13141 | } |
| 13142 | }, |
| 13143 | } |
| 13144 | } |
| 13080 | 13145 | } |
| 13081 | 13146 | |
| 13082 | 13147 | fn netSendUnavailable( |