diff options
Diffstat (limited to 'lib/std/os.zig')
| -rw-r--r-- | lib/std/os.zig | 45 |
1 files changed, 32 insertions, 13 deletions
diff --git a/lib/std/os.zig b/lib/std/os.zig index be1fe3e5f4..7967811672 100644 --- a/lib/std/os.zig +++ b/lib/std/os.zig @@ -5378,22 +5378,41 @@ pub const SetSockOptError = error{ /// Insufficient resources are available in the system to complete the call. SystemResources, + + NetworkSubsystemFailed, + FileDescriptorNotASocket, + SocketNotBound, } || UnexpectedError; /// Set a socket's options. -pub fn setsockopt(fd: fd_t, level: u32, optname: u32, opt: []const u8) SetSockOptError!void { - switch (errno(system.setsockopt(fd, level, optname, opt.ptr, @intCast(socklen_t, opt.len)))) { - 0 => {}, - EBADF => unreachable, // always a race condition - ENOTSOCK => unreachable, // always a race condition - EINVAL => unreachable, - EFAULT => unreachable, - EDOM => return error.TimeoutTooBig, - EISCONN => return error.AlreadyConnected, - ENOPROTOOPT => return error.InvalidProtocolOption, - ENOMEM => return error.SystemResources, - ENOBUFS => return error.SystemResources, - else => |err| return unexpectedErrno(err), +pub fn setsockopt(fd: socket_t, level: u32, optname: u32, opt: []const u8) SetSockOptError!void { + if (builtin.os.tag == .windows) { + const rc = windows.ws2_32.setsockopt(fd, level, optname, opt.ptr, @intCast(socklen_t, opt.len)); + if (rc == windows.ws2_32.SOCKET_ERROR) { + switch (windows.ws2_32.WSAGetLastError()) { + .WSANOTINITIALISED => unreachable, + .WSAENETDOWN => return error.NetworkSubsystemFailed, + .WSAEFAULT => unreachable, + .WSAENOTSOCK => return error.FileDescriptorNotASocket, + .WSAEINVAL => return error.SocketNotBound, + else => |err| return windows.unexpectedWSAError(err), + } + } + return; + } else { + switch (errno(system.setsockopt(fd, level, optname, opt.ptr, @intCast(socklen_t, opt.len)))) { + 0 => {}, + EBADF => unreachable, // always a race condition + ENOTSOCK => unreachable, // always a race condition + EINVAL => unreachable, + EFAULT => unreachable, + EDOM => return error.TimeoutTooBig, + EISCONN => return error.AlreadyConnected, + ENOPROTOOPT => return error.InvalidProtocolOption, + ENOMEM => return error.SystemResources, + ENOBUFS => return error.SystemResources, + else => |err| return unexpectedErrno(err), + } } } |
