const std = @import("std"); const ControlMessage = extern struct { const Level = enum(u32) { socket = std.posix.SOL.SOCKET, }; // WARNING: this kind enum might be wrong for non-linux posix systems. const Kind = enum(u32) { rights = 1, credentials = 2, }; const Header = extern struct { length: usize, level: Level, kind: Kind, }; header: Header, payload: extern union { fd: [255]std.posix.fd_t, }, pub fn alignment(length: usize) usize { return (length + @sizeOf(usize) - 1) & ~(@as(usize, @sizeOf(usize) - 1)); } pub fn space(length: usize) usize { return alignment(length) + alignment(@sizeOf(Header)); } pub fn from_fds(fds: []std.posix.fd_t) @This() { var self: @This() = undefined; self.header.level = .socket; self.header.kind = .rights; self.header.length = alignment(@sizeOf(Header)) + (fds.len * @sizeOf(std.posix.fd_t)); @memcpy(self.payload.fd[0..fds.len], fds); return self; } }; pub fn send_fds(socket: std.posix.socket_t, fds: []std.posix.fd_t, data: []const u8) !void { var cmsg: ControlMessage = .from_fds(fds); const io = std.posix.iovec { .base = @constCast(@ptrCast(data)), .len = data.len, }; const msghdr = std.posix.msghdr_const { .name = null, .namelen = 0, .iov = @ptrCast(&io), .iovlen = 1, .control = &cmsg, .controllen = @intCast(ControlMessage.space(fds.len)), .flags = 0, }; _ = try std.posix.sendmsg(socket, &msghdr, 0); }