mirror of
https://github.com/ziglang/zig.git
synced 2025-12-06 14:23:09 +00:00
std.os: WSAStartup is now called upon socket creation when needed
This commit is contained in:
parent
df56bf94a2
commit
85c2ffc9ba
@ -2724,6 +2724,9 @@ pub const SocketError = error{
|
|||||||
|
|
||||||
/// The socket type is not supported by the protocol.
|
/// The socket type is not supported by the protocol.
|
||||||
SocketTypeNotSupported,
|
SocketTypeNotSupported,
|
||||||
|
|
||||||
|
/// The environment for socket control has not been initialised.
|
||||||
|
NotInitialised,
|
||||||
} || UnexpectedError;
|
} || UnexpectedError;
|
||||||
|
|
||||||
pub fn socket(domain: u32, socket_type: u32, protocol: u32) SocketError!socket_t {
|
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
|
// 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 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 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;
|
errdefer windows.closesocket(rc) catch unreachable;
|
||||||
if ((socket_type & SOCK_NONBLOCK) != 0) {
|
if ((socket_type & SOCK_NONBLOCK) != 0) {
|
||||||
var mode: c_ulong = 1; // nonblocking
|
var mode: c_ulong = 1; // nonblocking
|
||||||
|
|||||||
@ -1295,6 +1295,7 @@ pub fn WSASocketW(
|
|||||||
.WSAEMFILE => return error.ProcessFdQuotaExceeded,
|
.WSAEMFILE => return error.ProcessFdQuotaExceeded,
|
||||||
.WSAENOBUFS => return error.SystemResources,
|
.WSAENOBUFS => return error.SystemResources,
|
||||||
.WSAEPROTONOSUPPORT => return error.ProtocolNotSupported,
|
.WSAEPROTONOSUPPORT => return error.ProtocolNotSupported,
|
||||||
|
.WSANOTINITIALISED => return error.NotInitialised,
|
||||||
else => |err| return unexpectedWSAError(err),
|
else => |err| return unexpectedWSAError(err),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user