os: make msghdr, msghdr_const, and sockaddr_storage backwards-compatible

`msghdr` and `msghdr_const` definitions have been added back the way
they were in std.os. std.os.sendmsg has also been modified to accept a
msghdr_const again to ensure backwards-compatibility with this PR.
Underneath the hood, std.os.sendmsg will @ptrCast the provided
msghdr_const into a std.x.os.Socket.Message.

`sockaddr_storage` definitions have been added back the way they were in
std.os, except that it now simply aliases
std.x.os.Socket.Address.Native.Storage as all of
std.x.os.Socket.Address.Native.Storage's fields are equivalent to the
fields that were previously defined for std.x.os.bits.sockaddr_storage.

std.x.os.Socket.sendMessage now no longer is a stub that aliases
std.os.sendmsg, but instead calls and handles
errors from std.os.system.sendmsg directly.

Addresses feedback to urge backwards compatibility from @andrewrk.
This commit is contained in:
Kenta Iwasaki
2021-05-31 19:29:17 +09:00
parent 6950e4c294
commit aad8491dbd
17 changed files with 413 additions and 5 deletions

View File

@@ -4994,11 +4994,11 @@ pub fn sendmsg(
/// The file descriptor of the sending socket.
sockfd: socket_t,
/// Message header and iovecs
msg: std.x.os.Socket.Message,
msg: msghdr_const,
flags: u32,
) SendMsgError!usize {
while (true) {
const rc = system.sendmsg(sockfd, &msg, @intCast(c_int, flags));
const rc = system.sendmsg(sockfd, @ptrCast(*const std.x.os.Socket.Message, &msg), @intCast(c_int, flags));
if (builtin.os.tag == .windows) {
if (rc == windows.ws2_32.SOCKET_ERROR) {
switch (windows.ws2_32.WSAGetLastError()) {

View File

@@ -23,6 +23,7 @@ pub const sockaddr = extern struct {
family: sa_family_t,
data: [14]u8,
};
pub const sockaddr_storage = std.x.os.Socket.Address.Native.Storage;
pub const sockaddr_in = extern struct {
len: u8 = @sizeOf(sockaddr_in),
family: sa_family_t = AF_INET,

View File

@@ -396,6 +396,8 @@ pub const sockaddr = extern struct {
data: [14]u8,
};
pub const sockaddr_storage = std.x.os.Socket.Address.Native.Storage;
pub const Kevent = extern struct {
ident: usize,
filter: c_short,
@@ -773,6 +775,15 @@ pub const cmsghdr = extern struct {
cmsg_level: c_int,
cmsg_type: c_int,
};
pub const msghdr = extern struct {
msg_name: ?*c_void,
msg_namelen: socklen_t,
msg_iov: [*c]iovec,
msg_iovlen: c_int,
msg_control: ?*c_void,
msg_controllen: socklen_t,
msg_flags: c_int,
};
pub const cmsgcred = extern struct {
cmcred_pid: pid_t,
cmcred_uid: uid_t,

View File

@@ -82,6 +82,52 @@ pub const Flock = extern struct {
__unused: [4]u8,
};
pub const msghdr = extern struct {
/// optional address
msg_name: ?*sockaddr,
/// size of address
msg_namelen: socklen_t,
/// scatter/gather array
msg_iov: [*]iovec,
/// # elements in msg_iov
msg_iovlen: i32,
/// ancillary data
msg_control: ?*c_void,
/// ancillary data buffer len
msg_controllen: socklen_t,
/// flags on received message
msg_flags: i32,
};
pub const msghdr_const = extern struct {
/// optional address
msg_name: ?*const sockaddr,
/// size of address
msg_namelen: socklen_t,
/// scatter/gather array
msg_iov: [*]iovec_const,
/// # elements in msg_iov
msg_iovlen: i32,
/// ancillary data
msg_control: ?*c_void,
/// ancillary data buffer len
msg_controllen: socklen_t,
/// flags on received message
msg_flags: i32,
};
pub const libc_stat = extern struct {
dev: dev_t,
ino: ino_t,
@@ -160,6 +206,8 @@ pub const sockaddr = extern struct {
data: [14]u8,
};
pub const sockaddr_storage = std.x.os.Socket.Address.Native.Storage;
pub const sockaddr_in = extern struct {
len: u8 = @sizeOf(sockaddr_in),
family: sa_family_t = AF_INET,

View File

@@ -73,6 +73,52 @@ pub const Flock = extern struct {
__unused: [4]u8,
};
pub const msghdr = extern struct {
/// optional address
msg_name: ?*sockaddr,
/// size of address
msg_namelen: socklen_t,
/// scatter/gather array
msg_iov: [*]iovec,
/// # elements in msg_iov
msg_iovlen: i32,
/// ancillary data
msg_control: ?*c_void,
/// ancillary data buffer len
msg_controllen: socklen_t,
/// flags on received message
msg_flags: i32,
};
pub const msghdr_const = extern struct {
/// optional address
msg_name: ?*const sockaddr,
/// size of address
msg_namelen: socklen_t,
/// scatter/gather array
msg_iov: [*]iovec_const,
/// # elements in msg_iov
msg_iovlen: i32,
/// ancillary data
msg_control: ?*c_void,
/// ancillary data buffer len
msg_controllen: socklen_t,
/// flags on received message
msg_flags: i32,
};
pub const off_t = i64;
pub const ino_t = u64;
@@ -193,6 +239,8 @@ pub const sockaddr = extern struct {
data: [14]u8,
};
pub const sockaddr_storage = std.x.os.Socket.Address.Native.Storage;
pub const sockaddr_in = extern struct {
len: u8 = @sizeOf(sockaddr_in),
family: sa_family_t = AF_INET,

View File

@@ -1149,6 +1149,8 @@ pub const sockaddr = extern struct {
data: [14]u8,
};
pub const sockaddr_storage = std.x.os.Socket.Address.Native.Storage;
/// IPv4 socket address
pub const sockaddr_in = extern struct {
family: sa_family_t = AF_INET,
@@ -1173,12 +1175,12 @@ pub const sockaddr_un = extern struct {
};
pub const mmsghdr = extern struct {
msg_hdr: std.x.os.Socket.Message,
msg_hdr: msghdr,
msg_len: u32,
};
pub const mmsghdr_const = extern struct {
msg_hdr: std.x.os.Socket.Message,
msg_hdr: msghdr_const,
msg_len: u32,
};

View File

@@ -526,6 +526,26 @@ pub const Flock = extern struct {
__unused: [4]u8,
};
pub const msghdr = extern struct {
msg_name: ?*sockaddr,
msg_namelen: socklen_t,
msg_iov: [*]iovec,
msg_iovlen: i32,
msg_control: ?*c_void,
msg_controllen: socklen_t,
msg_flags: i32,
};
pub const msghdr_const = extern struct {
msg_name: ?*const sockaddr,
msg_namelen: socklen_t,
msg_iov: [*]iovec_const,
msg_iovlen: i32,
msg_control: ?*c_void,
msg_controllen: socklen_t,
msg_flags: i32,
};
pub const blksize_t = i32;
pub const nlink_t = u32;
pub const time_t = isize;

View File

@@ -395,6 +395,30 @@ pub const Flock = extern struct {
__unused: [4]u8,
};
pub const msghdr = extern struct {
msg_name: ?*sockaddr,
msg_namelen: socklen_t,
msg_iov: [*]iovec,
msg_iovlen: i32,
__pad1: i32 = 0,
msg_control: ?*c_void,
msg_controllen: socklen_t,
__pad2: socklen_t = 0,
msg_flags: i32,
};
pub const msghdr_const = extern struct {
msg_name: ?*const sockaddr,
msg_namelen: socklen_t,
msg_iov: [*]iovec_const,
msg_iovlen: i32,
__pad1: i32 = 0,
msg_control: ?*c_void,
msg_controllen: socklen_t,
__pad2: socklen_t = 0,
msg_flags: i32,
};
pub const blksize_t = i32;
pub const nlink_t = u32;
pub const time_t = isize;

View File

@@ -523,6 +523,26 @@ pub const Flock = extern struct {
l_pid: pid_t,
};
pub const msghdr = extern struct {
msg_name: ?*sockaddr,
msg_namelen: socklen_t,
msg_iov: [*]iovec,
msg_iovlen: i32,
msg_control: ?*c_void,
msg_controllen: socklen_t,
msg_flags: i32,
};
pub const msghdr_const = extern struct {
msg_name: ?*const sockaddr,
msg_namelen: socklen_t,
msg_iov: [*]iovec_const,
msg_iovlen: i32,
msg_control: ?*c_void,
msg_controllen: socklen_t,
msg_flags: i32,
};
pub const blksize_t = i32;
pub const nlink_t = u32;
pub const time_t = isize;

View File

@@ -515,6 +515,26 @@ pub const Flock = extern struct {
l_pid: pid_t,
};
pub const msghdr = extern struct {
msg_name: ?*sockaddr,
msg_namelen: socklen_t,
msg_iov: [*]iovec,
msg_iovlen: usize,
msg_control: ?*c_void,
msg_controllen: socklen_t,
msg_flags: i32,
};
pub const msghdr_const = extern struct {
msg_name: ?*const sockaddr,
msg_namelen: socklen_t,
msg_iov: [*]iovec_const,
msg_iovlen: usize,
msg_control: ?*c_void,
msg_controllen: socklen_t,
msg_flags: i32,
};
pub const blksize_t = i32;
pub const nlink_t = u32;
pub const time_t = isize;

View File

@@ -491,6 +491,26 @@ pub const Flock = extern struct {
__unused: [4]u8,
};
pub const msghdr = extern struct {
msg_name: ?*sockaddr,
msg_namelen: socklen_t,
msg_iov: [*]iovec,
msg_iovlen: usize,
msg_control: ?*c_void,
msg_controllen: usize,
msg_flags: i32,
};
pub const msghdr_const = extern struct {
msg_name: ?*const sockaddr,
msg_namelen: socklen_t,
msg_iov: [*]iovec_const,
msg_iovlen: usize,
msg_control: ?*c_void,
msg_controllen: usize,
msg_flags: i32,
};
pub const blksize_t = i64;
pub const nlink_t = u64;
pub const time_t = i64;

View File

@@ -465,6 +465,26 @@ pub const Flock = extern struct {
l_pid: pid_t,
};
pub const msghdr = extern struct {
msg_name: ?*sockaddr,
msg_namelen: socklen_t,
msg_iov: [*]iovec,
msg_iovlen: u64,
msg_control: ?*c_void,
msg_controllen: u64,
msg_flags: i32,
};
pub const msghdr_const = extern struct {
msg_name: ?*const sockaddr,
msg_namelen: socklen_t,
msg_iov: [*]iovec_const,
msg_iovlen: u64,
msg_control: ?*c_void,
msg_controllen: u64,
msg_flags: i32,
};
pub const off_t = i64;
pub const ino_t = u64;
pub const mode_t = u32;

View File

@@ -489,6 +489,30 @@ pub const Flock = extern struct {
l_pid: pid_t,
};
pub const msghdr = extern struct {
msg_name: ?*sockaddr,
msg_namelen: socklen_t,
msg_iov: [*]iovec,
msg_iovlen: i32,
__pad1: i32 = 0,
msg_control: ?*c_void,
msg_controllen: socklen_t,
__pad2: socklen_t = 0,
msg_flags: i32,
};
pub const msghdr_const = extern struct {
msg_name: ?*const sockaddr,
msg_namelen: socklen_t,
msg_iov: [*]iovec_const,
msg_iovlen: i32,
__pad1: i32 = 0,
msg_control: ?*c_void,
msg_controllen: socklen_t,
__pad2: socklen_t = 0,
msg_flags: i32,
};
pub const off_t = i64;
pub const ino_t = u64;
pub const dev_t = u64;

View File

@@ -108,6 +108,52 @@ pub const EAI = enum(c_int) {
pub const EAI_MAX = 15;
pub const msghdr = extern struct {
/// optional address
msg_name: ?*sockaddr,
/// size of address
msg_namelen: socklen_t,
/// scatter/gather array
msg_iov: [*]iovec,
/// # elements in msg_iov
msg_iovlen: i32,
/// ancillary data
msg_control: ?*c_void,
/// ancillary data buffer len
msg_controllen: socklen_t,
/// flags on received message
msg_flags: i32,
};
pub const msghdr_const = extern struct {
/// optional address
msg_name: ?*const sockaddr,
/// size of address
msg_namelen: socklen_t,
/// scatter/gather array
msg_iov: [*]iovec_const,
/// # elements in msg_iov
msg_iovlen: i32,
/// ancillary data
msg_control: ?*c_void,
/// ancillary data buffer len
msg_controllen: socklen_t,
/// flags on received message
msg_flags: i32,
};
pub const libc_stat = extern struct {
dev: dev_t,
mode: mode_t,
@@ -180,6 +226,8 @@ pub const sockaddr = extern struct {
data: [14]u8,
};
pub const sockaddr_storage = std.x.os.Socket.Address.Native.Storage;
pub const sockaddr_in = extern struct {
len: u8 = @sizeOf(sockaddr_in),
family: sa_family_t = AF_INET,

View File

@@ -124,6 +124,52 @@ pub const EAI = enum(c_int) {
pub const EAI_MAX = 15;
pub const msghdr = extern struct {
/// optional address
msg_name: ?*sockaddr,
/// size of address
msg_namelen: socklen_t,
/// scatter/gather array
msg_iov: [*]iovec,
/// # elements in msg_iov
msg_iovlen: c_uint,
/// ancillary data
msg_control: ?*c_void,
/// ancillary data buffer len
msg_controllen: socklen_t,
/// flags on received message
msg_flags: c_int,
};
pub const msghdr_const = extern struct {
/// optional address
msg_name: ?*const sockaddr,
/// size of address
msg_namelen: socklen_t,
/// scatter/gather array
msg_iov: [*]iovec_const,
/// # elements in msg_iov
msg_iovlen: c_uint,
/// ancillary data
msg_control: ?*c_void,
/// ancillary data buffer len
msg_controllen: socklen_t,
/// flags on received message
msg_flags: c_int,
};
pub const libc_stat = extern struct {
mode: mode_t,
dev: dev_t,
@@ -200,6 +246,8 @@ pub const sockaddr = extern struct {
data: [14]u8,
};
pub const sockaddr_storage = std.x.os.Socket.Address.Native.Storage;
pub const sockaddr_in = extern struct {
len: u8 = @sizeOf(sockaddr_in),
family: sa_family_t = AF_INET,

View File

@@ -1059,6 +1059,8 @@ pub const sockaddr = extern struct {
data: [14]u8,
};
pub const sockaddr_storage = std.x.os.Socket.Address.Native.Storage;
/// IPv4 socket address
pub const sockaddr_in = extern struct {
family: ADDRESS_FAMILY = AF_INET,
@@ -1087,6 +1089,27 @@ pub const WSABUF = extern struct {
buf: [*]u8,
};
pub const msghdr = WSAMSG;
pub const msghdr_const = WSAMSG_const;
pub const WSAMSG_const = extern struct {
name: *const sockaddr,
namelen: INT,
lpBuffers: [*]WSABUF,
dwBufferCount: DWORD,
Control: WSABUF,
dwFlags: DWORD,
};
pub const WSAMSG = extern struct {
name: *sockaddr,
namelen: INT,
lpBuffers: [*]WSABUF,
dwBufferCount: DWORD,
Control: WSABUF,
dwFlags: DWORD,
};
pub const WSAPOLLFD = pollfd;
pub const pollfd = extern struct {

View File

@@ -79,7 +79,38 @@ pub fn Mixin(comptime Socket: type) type {
/// with a set of flags specified. It returns the number of bytes that are
/// written to the socket.
pub fn writeMessage(self: Socket, msg: Socket.Message, flags: u32) !usize {
return os.sendmsg(self.fd, msg, flags);
while (true) {
const rc = os.system.sendmsg(self.fd, &msg, @intCast(c_int, flags));
return switch (os.errno(rc)) {
0 => return @intCast(usize, rc),
os.EACCES => error.AccessDenied,
os.EAGAIN => error.WouldBlock,
os.EALREADY => error.FastOpenAlreadyInProgress,
os.EBADF => unreachable, // always a race condition
os.ECONNRESET => error.ConnectionResetByPeer,
os.EDESTADDRREQ => unreachable, // The socket is not connection-mode, and no peer address is set.
os.EFAULT => unreachable, // An invalid user space address was specified for an argument.
os.EINTR => continue,
os.EINVAL => unreachable, // Invalid argument passed.
os.EISCONN => unreachable, // connection-mode socket was connected already but a recipient was specified
os.EMSGSIZE => error.MessageTooBig,
os.ENOBUFS => error.SystemResources,
os.ENOMEM => error.SystemResources,
os.ENOTSOCK => unreachable, // The file descriptor sockfd does not refer to a socket.
os.EOPNOTSUPP => unreachable, // Some bit in the flags argument is inappropriate for the socket type.
os.EPIPE => error.BrokenPipe,
os.EAFNOSUPPORT => error.AddressFamilyNotSupported,
os.ELOOP => error.SymLinkLoop,
os.ENAMETOOLONG => error.NameTooLong,
os.ENOENT => error.FileNotFound,
os.ENOTDIR => error.NotDir,
os.EHOSTUNREACH => error.NetworkUnreachable,
os.ENETUNREACH => error.NetworkUnreachable,
os.ENOTCONN => error.SocketNotConnected,
os.ENETDOWN => error.NetworkSubsystemFailed,
else => |err| os.unexpectedErrno(err),
};
}
}
/// Read multiple I/O vectors with a prepended message header from the socket