From 85c2ffc9ba3153fbc5d295b2bc698b5bf0344d0e Mon Sep 17 00:00:00 2001 From: Bxil Date: Wed, 5 May 2021 21:38:02 +0200 Subject: std.os: WSAStartup is now called upon socket creation when needed --- lib/std/os.zig | 17 ++++++++++++++++- lib/std/os/windows.zig | 1 + 2 files changed, 17 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/std/os.zig b/lib/std/os.zig index f33e206a65..d7da67272f 100644 --- a/lib/std/os.zig +++ b/lib/std/os.zig @@ -2724,6 +2724,9 @@ pub const SocketError = error{ /// The socket type is not supported by the protocol. SocketTypeNotSupported, + + /// The environment for socket control has not been initialised. + NotInitialised, } || UnexpectedError; 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 // NOTE: windows translates the SOCK_NONBLOCK/SOCK_CLOEXEC flags into windows-analagous operations const filtered_sock_type = socket_type & ~@as(u32, SOCK_NONBLOCK | SOCK_CLOEXEC); const flags: u32 = if ((socket_type & SOCK_CLOEXEC) != 0) windows.ws2_32.WSA_FLAG_NO_HANDLE_INHERIT else 0; - const rc = try windows.WSASocketW(@bitCast(i32, domain), @bitCast(i32, filtered_sock_type), @bitCast(i32, protocol), null, 0, flags); + const rc = windows.WSASocketW(@bitCast(i32, domain), @bitCast(i32, filtered_sock_type), @bitCast(i32, protocol), null, 0, flags) catch |err| switch (err) { + error.NotInitialised => again: { + // Before a socket is made Windows requires WSAStartup to be called. + // 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. + // WSAStartup is supposed to have a pair in the form of WSACleanup to call once all socket operations concluded. + // As of writing that function is never called. + _ = windows.WSAStartup(2, 2) catch { + return error.NotInitialised; + }; + break :again try windows.WSASocketW(@bitCast(i32, domain), @bitCast(i32, filtered_sock_type), @bitCast(i32, protocol), null, 0, flags); + }, + else => return err, + }; errdefer windows.closesocket(rc) catch unreachable; if ((socket_type & SOCK_NONBLOCK) != 0) { var mode: c_ulong = 1; // nonblocking diff --git a/lib/std/os/windows.zig b/lib/std/os/windows.zig index db261c0ecc..db9cc98fdf 100644 --- a/lib/std/os/windows.zig +++ b/lib/std/os/windows.zig @@ -1295,6 +1295,7 @@ pub fn WSASocketW( .WSAEMFILE => return error.ProcessFdQuotaExceeded, .WSAENOBUFS => return error.SystemResources, .WSAEPROTONOSUPPORT => return error.ProtocolNotSupported, + .WSANOTINITIALISED => return error.NotInitialised, else => |err| return unexpectedWSAError(err), } } -- cgit v1.2.3