authorgravatar for ryansmake@gmail.comBxil <ryansmake@gmail.com> 2021-05-05 21:38:02+02:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-05-20 11:22:55-07:00
log85c2ffc9ba3153fbc5d295b2bc698b5bf0344d0e
tree9d3ca871c80fcb4ce7ea8e5108bee4cc36bb2e93
parentdf56bf94a2a3d1ddef891a90a5b1ee077b5dd6c9

std.os: WSAStartup is now called upon socket creation when needed


2 files changed, 17 insertions(+), 1 deletions(-)

lib/std/os.zig+16-1
...@@ -2724,6 +2724,9 @@ pub const SocketError = error{...@@ -2724,6 +2724,9 @@ pub const SocketError = error{
27242724
2725 /// The socket type is not supported by the protocol.2725 /// The socket type is not supported by the protocol.
2726 SocketTypeNotSupported,2726 SocketTypeNotSupported,
2727
2728 /// The environment for socket control has not been initialised.
2729 NotInitialised,
2727} || UnexpectedError;2730} || UnexpectedError;
27282731
2729pub fn socket(domain: u32, socket_type: u32, protocol: u32) SocketError!socket_t {2732pub fn socket(domain: u32, socket_type: u32, protocol: u32) SocketError!socket_t {
...@@ -2731,7 +2734,19 @@ pub fn socket(domain: u32, socket_type: u32, protocol: u32) SocketError!socket_t...@@ -2731,7 +2734,19 @@ pub fn socket(domain: u32, socket_type: u32, protocol: u32) SocketError!socket_t
2731 // NOTE: windows translates the SOCK_NONBLOCK/SOCK_CLOEXEC flags into windows-analagous operations2734 // NOTE: windows translates the SOCK_NONBLOCK/SOCK_CLOEXEC flags into windows-analagous operations
2732 const filtered_sock_type = socket_type & ~@as(u32, SOCK_NONBLOCK | SOCK_CLOEXEC);2735 const filtered_sock_type = socket_type & ~@as(u32, SOCK_NONBLOCK | SOCK_CLOEXEC);
2733 const flags: u32 = if ((socket_type & SOCK_CLOEXEC) != 0) windows.ws2_32.WSA_FLAG_NO_HANDLE_INHERIT else 0;2736 const flags: u32 = if ((socket_type & SOCK_CLOEXEC) != 0) windows.ws2_32.WSA_FLAG_NO_HANDLE_INHERIT else 0;
2734 const rc = try windows.WSASocketW(@bitCast(i32, domain), @bitCast(i32, filtered_sock_type), @bitCast(i32, protocol), null, 0, flags);2737 const rc = windows.WSASocketW(@bitCast(i32, domain), @bitCast(i32, filtered_sock_type), @bitCast(i32, protocol), null, 0, flags) catch |err| switch (err) {
2738 error.NotInitialised => again: {
2739 // Before a socket is made Windows requires WSAStartup to be called.
2740 // Let's try doing that now, then make the socket again. If socket creation still fails then there is an underlying issue we cannot solve.
2741 // WSAStartup is supposed to have a pair in the form of WSACleanup to call once all socket operations concluded.
2742 // As of writing that function is never called.
2743 _ = windows.WSAStartup(2, 2) catch {
2744 return error.NotInitialised;
2745 };
2746 break :again try windows.WSASocketW(@bitCast(i32, domain), @bitCast(i32, filtered_sock_type), @bitCast(i32, protocol), null, 0, flags);
2747 },
2748 else => return err,
2749 };
2735 errdefer windows.closesocket(rc) catch unreachable;2750 errdefer windows.closesocket(rc) catch unreachable;
2736 if ((socket_type & SOCK_NONBLOCK) != 0) {2751 if ((socket_type & SOCK_NONBLOCK) != 0) {
2737 var mode: c_ulong = 1; // nonblocking2752 var mode: c_ulong = 1; // nonblocking
lib/std/os/windows.zig+1
...@@ -1295,6 +1295,7 @@ pub fn WSASocketW(...@@ -1295,6 +1295,7 @@ pub fn WSASocketW(
1295 .WSAEMFILE => return error.ProcessFdQuotaExceeded,1295 .WSAEMFILE => return error.ProcessFdQuotaExceeded,
1296 .WSAENOBUFS => return error.SystemResources,1296 .WSAENOBUFS => return error.SystemResources,
1297 .WSAEPROTONOSUPPORT => return error.ProtocolNotSupported,1297 .WSAEPROTONOSUPPORT => return error.ProtocolNotSupported,
1298 .WSANOTINITIALISED => return error.NotInitialised,
1298 else => |err| return unexpectedWSAError(err),1299 else => |err| return unexpectedWSAError(err),
1299 }1300 }
1300 }1301 }