mirror of
https://github.com/ziglang/zig.git
synced 2026-01-20 22:35:24 +00:00
socketpair: posix wrapper, void on windows
socketpair is something like a pipe2() for sockets, and generally only works for AF_UNIX sockets for most platforms. Winsock2 explicitly does not support this call, even though it does have AF_UNIX sockets.
This commit is contained in:
parent
05cff8a558
commit
79313d844f
@ -10599,6 +10599,12 @@ pub const socket = switch (native_os) {
|
||||
else => private.socket,
|
||||
};
|
||||
|
||||
pub const socketpair = switch (native_os) {
|
||||
// https://devblogs.microsoft.com/commandline/af_unix-comes-to-windows/#unsupported\unavailable:
|
||||
.windows => void,
|
||||
else => private.socketpair,
|
||||
};
|
||||
|
||||
pub const stat = switch (native_os) {
|
||||
.macos => switch (native_arch) {
|
||||
.x86_64 => private.@"stat$INODE64",
|
||||
@ -10740,7 +10746,6 @@ pub extern "c" fn uname(buf: *utsname) c_int;
|
||||
pub extern "c" fn gethostname(name: [*]u8, len: usize) c_int;
|
||||
pub extern "c" fn shutdown(socket: fd_t, how: c_int) c_int;
|
||||
pub extern "c" fn bind(socket: fd_t, address: ?*const sockaddr, address_len: socklen_t) c_int;
|
||||
pub extern "c" fn socketpair(domain: c_uint, sock_type: c_uint, protocol: c_uint, sv: *[2]fd_t) c_int;
|
||||
pub extern "c" fn listen(sockfd: fd_t, backlog: c_uint) c_int;
|
||||
pub extern "c" fn getsockname(sockfd: fd_t, noalias addr: *sockaddr, noalias addrlen: *socklen_t) c_int;
|
||||
pub extern "c" fn getpeername(sockfd: fd_t, noalias addr: *sockaddr, noalias addrlen: *socklen_t) c_int;
|
||||
@ -11429,6 +11434,7 @@ const private = struct {
|
||||
extern "c" fn sigismember(set: ?*const sigset_t, signo: c_int) c_int;
|
||||
extern "c" fn sigprocmask(how: c_int, noalias set: ?*const sigset_t, noalias oset: ?*sigset_t) c_int;
|
||||
extern "c" fn socket(domain: c_uint, sock_type: c_uint, protocol: c_uint) c_int;
|
||||
extern "c" fn socketpair(domain: c_uint, sock_type: c_uint, protocol: c_uint, sv: *[2]fd_t) c_int;
|
||||
extern "c" fn stat(noalias path: [*:0]const u8, noalias buf: *Stat) c_int;
|
||||
extern "c" fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) c_int;
|
||||
extern "c" fn sysconf(sc: c_int) c_long;
|
||||
|
||||
@ -3671,6 +3671,46 @@ pub fn socket(domain: u32, socket_type: u32, protocol: u32) SocketError!socket_t
|
||||
}
|
||||
}
|
||||
|
||||
pub fn socketpair(domain: u32, socket_type: u32, protocol: u32) SocketError![2]socket_t {
|
||||
// Note to the future: we could provide a shim here for e.g. windows which
|
||||
// creates a listening socket, then creates a second socket and connects it
|
||||
// to the listening socket, and then returns the two.
|
||||
if (@TypeOf(system.socketpair) == void)
|
||||
@compileError("socketpair() not supported by this OS");
|
||||
|
||||
// I'm not really sure if haiku supports flags here. I'm following the
|
||||
// existing filter here from pipe2(), because it sure seems like it
|
||||
// supports flags there too, but haiku can be hard to understand.
|
||||
const have_sock_flags = !builtin.target.os.tag.isDarwin() and native_os != .haiku;
|
||||
const filtered_sock_type = if (!have_sock_flags)
|
||||
socket_type & ~@as(u32, SOCK.NONBLOCK | SOCK.CLOEXEC)
|
||||
else
|
||||
socket_type;
|
||||
var socks: [2]socket_t = undefined;
|
||||
const rc = system.socketpair(domain, filtered_sock_type, protocol, &socks);
|
||||
switch (errno(rc)) {
|
||||
.SUCCESS => {
|
||||
errdefer close(socks[0]);
|
||||
errdefer close(socks[1]);
|
||||
if (!have_sock_flags) {
|
||||
try setSockFlags(socks[0], socket_type);
|
||||
try setSockFlags(socks[1], socket_type);
|
||||
}
|
||||
return socks;
|
||||
},
|
||||
.ACCES => return error.AccessDenied,
|
||||
.AFNOSUPPORT => return error.AddressFamilyNotSupported,
|
||||
.INVAL => return error.ProtocolFamilyNotAvailable,
|
||||
.MFILE => return error.ProcessFdQuotaExceeded,
|
||||
.NFILE => return error.SystemFdQuotaExceeded,
|
||||
.NOBUFS => return error.SystemResources,
|
||||
.NOMEM => return error.SystemResources,
|
||||
.PROTONOSUPPORT => return error.ProtocolNotSupported,
|
||||
.PROTOTYPE => return error.SocketTypeNotSupported,
|
||||
else => |err| return unexpectedErrno(err),
|
||||
}
|
||||
}
|
||||
|
||||
pub const ShutdownError = error{
|
||||
ConnectionAborted,
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user