update some syscall APIs to use the new flags

Add Shut, PF, AF, IPPROTO types

Update IoUring and test to use some of this flags

TODO: avoid breaking API and make transitioning smooth
Instead mark the previous API as deprecated for at least
One zig release while using the new in the Zig codebase

Signed-off-by: Bernard Assan <mega.alpha100@gmail.com>
This commit is contained in:
Bernard Assan 2025-10-02 17:22:55 +00:00
parent af2397777a
commit b5dab22f26
No known key found for this signature in database
GPG key ID: C2A2C53574321095
4 changed files with 168 additions and 186 deletions

View file

@ -187,7 +187,7 @@ pub fn cwd() Dir {
} else if (native_os == .wasi) { } else if (native_os == .wasi) {
return .{ .fd = std.options.wasiCwd() }; return .{ .fd = std.options.wasiCwd() };
} else { } else {
return .{ .fd = posix.AT.FDCWD }; return .{ .fd = posix.AT.fdcwd };
} }
} }

View file

@ -921,7 +921,7 @@ pub fn readlink(noalias path: [*:0]const u8, noalias buf_ptr: [*]u8, buf_len: us
if (@hasField(SYS, "readlink")) { if (@hasField(SYS, "readlink")) {
return syscall3(.readlink, @intFromPtr(path), @intFromPtr(buf_ptr), buf_len); return syscall3(.readlink, @intFromPtr(path), @intFromPtr(buf_ptr), buf_len);
} else { } else {
return syscall4(.readlinkat, @as(usize, @bitCast(@as(isize, AT.FDCWD))), @intFromPtr(path), @intFromPtr(buf_ptr), buf_len); return syscall4(.readlinkat, @as(usize, @bitCast(@as(isize, At.fdcwd))), @intFromPtr(path), @intFromPtr(buf_ptr), buf_len);
} }
} }
@ -933,7 +933,7 @@ pub fn mkdir(path: [*:0]const u8, mode: mode_t) usize {
if (@hasField(SYS, "mkdir")) { if (@hasField(SYS, "mkdir")) {
return syscall2(.mkdir, @intFromPtr(path), mode); return syscall2(.mkdir, @intFromPtr(path), mode);
} else { } else {
return syscall3(.mkdirat, @as(usize, @bitCast(@as(isize, AT.FDCWD))), @intFromPtr(path), mode); return syscall3(.mkdirat, @as(usize, @bitCast(@as(isize, At.fdcwd))), @intFromPtr(path), mode);
} }
} }
@ -945,7 +945,7 @@ pub fn mknod(path: [*:0]const u8, mode: u32, dev: u32) usize {
if (@hasField(SYS, "mknod")) { if (@hasField(SYS, "mknod")) {
return syscall3(.mknod, @intFromPtr(path), mode, dev); return syscall3(.mknod, @intFromPtr(path), mode, dev);
} else { } else {
return mknodat(AT.FDCWD, path, mode, dev); return mknodat(At.fdcwd, path, mode, dev);
} }
} }
@ -1178,7 +1178,7 @@ pub fn rmdir(path: [*:0]const u8) usize {
if (@hasField(SYS, "rmdir")) { if (@hasField(SYS, "rmdir")) {
return syscall1(.rmdir, @intFromPtr(path)); return syscall1(.rmdir, @intFromPtr(path));
} else { } else {
return syscall3(.unlinkat, @as(usize, @bitCast(@as(isize, AT.FDCWD))), @intFromPtr(path), AT.REMOVEDIR); return syscall3(.unlinkat, @as(usize, @bitCast(@as(isize, At.fdcwd))), @intFromPtr(path), @as(u32, @bitCast(At{ .removedir_or_handle_fid = .{ .removedir = true } })));
} }
} }
@ -1186,7 +1186,7 @@ pub fn symlink(existing: [*:0]const u8, new: [*:0]const u8) usize {
if (@hasField(SYS, "symlink")) { if (@hasField(SYS, "symlink")) {
return syscall2(.symlink, @intFromPtr(existing), @intFromPtr(new)); return syscall2(.symlink, @intFromPtr(existing), @intFromPtr(new));
} else { } else {
return syscall3(.symlinkat, @intFromPtr(existing), @as(usize, @bitCast(@as(isize, AT.FDCWD))), @intFromPtr(new)); return syscall3(.symlinkat, @intFromPtr(existing), @as(usize, @bitCast(@as(isize, At.fdcwd))), @intFromPtr(new));
} }
} }
@ -1237,7 +1237,7 @@ pub fn access(path: [*:0]const u8, mode: u32) usize {
if (@hasField(SYS, "access")) { if (@hasField(SYS, "access")) {
return syscall2(.access, @intFromPtr(path), mode); return syscall2(.access, @intFromPtr(path), mode);
} else { } else {
return faccessat(AT.FDCWD, path, mode, 0); return faccessat(At.fdcwd, path, mode, 0);
} }
} }
@ -1338,9 +1338,9 @@ pub fn rename(old: [*:0]const u8, new: [*:0]const u8) usize {
if (@hasField(SYS, "rename")) { if (@hasField(SYS, "rename")) {
return syscall2(.rename, @intFromPtr(old), @intFromPtr(new)); return syscall2(.rename, @intFromPtr(old), @intFromPtr(new));
} else if (@hasField(SYS, "renameat")) { } else if (@hasField(SYS, "renameat")) {
return syscall4(.renameat, @as(usize, @bitCast(@as(isize, AT.FDCWD))), @intFromPtr(old), @as(usize, @bitCast(@as(isize, AT.FDCWD))), @intFromPtr(new)); return syscall4(.renameat, @as(usize, @bitCast(@as(isize, At.fdcwd))), @intFromPtr(old), @as(usize, @bitCast(@as(isize, At.fdcwd))), @intFromPtr(new));
} else { } else {
return syscall5(.renameat2, @as(usize, @bitCast(@as(isize, AT.FDCWD))), @intFromPtr(old), @as(usize, @bitCast(@as(isize, AT.FDCWD))), @intFromPtr(new), 0); return syscall5(.renameat2, @as(usize, @bitCast(@as(isize, At.fdcwd))), @intFromPtr(old), @as(usize, @bitCast(@as(isize, At.fdcwd))), @intFromPtr(new), 0);
} }
} }
@ -1382,7 +1382,7 @@ pub fn open(path: [*:0]const u8, flags: O, perm: mode_t) usize {
} else { } else {
return syscall4( return syscall4(
.openat, .openat,
@bitCast(@as(isize, AT.FDCWD)), @bitCast(@as(isize, At.fdcwd)),
@intFromPtr(path), @intFromPtr(path),
@as(u32, @bitCast(flags)), @as(u32, @bitCast(flags)),
perm, perm,
@ -1395,7 +1395,7 @@ pub fn create(path: [*:0]const u8, perm: mode_t) usize {
} }
pub fn openat(dirfd: i32, path: [*:0]const u8, flags: O, mode: mode_t) usize { pub fn openat(dirfd: i32, path: [*:0]const u8, flags: O, mode: mode_t) usize {
// dirfd could be negative, for example AT.FDCWD is -100 // dirfd could be negative, for example At.fdcwd is -100
return syscall4(.openat, @bitCast(@as(isize, dirfd)), @intFromPtr(path), @as(u32, @bitCast(flags)), mode); return syscall4(.openat, @bitCast(@as(isize, dirfd)), @intFromPtr(path), @as(u32, @bitCast(flags)), mode);
} }
@ -1421,7 +1421,7 @@ pub fn chmod(path: [*:0]const u8, mode: mode_t) usize {
if (@hasField(SYS, "chmod")) { if (@hasField(SYS, "chmod")) {
return syscall2(.chmod, @intFromPtr(path), mode); return syscall2(.chmod, @intFromPtr(path), mode);
} else { } else {
return fchmodat(AT.FDCWD, path, mode, 0); return fchmodat(At.fdcwd, path, mode, 0);
} }
} }
@ -1553,9 +1553,9 @@ pub fn link(oldpath: [*:0]const u8, newpath: [*:0]const u8) usize {
} else { } else {
return syscall5( return syscall5(
.linkat, .linkat,
@as(usize, @bitCast(@as(isize, AT.FDCWD))), @as(usize, @bitCast(@as(isize, At.fdcwd))),
@intFromPtr(oldpath), @intFromPtr(oldpath),
@as(usize, @bitCast(@as(isize, AT.FDCWD))), @as(usize, @bitCast(@as(isize, At.fdcwd))),
@intFromPtr(newpath), @intFromPtr(newpath),
0, 0,
); );
@ -1577,7 +1577,7 @@ pub fn unlink(path: [*:0]const u8) usize {
if (@hasField(SYS, "unlink")) { if (@hasField(SYS, "unlink")) {
return syscall1(.unlink, @intFromPtr(path)); return syscall1(.unlink, @intFromPtr(path));
} else { } else {
return syscall3(.unlinkat, @as(usize, @bitCast(@as(isize, AT.FDCWD))), @intFromPtr(path), 0); return syscall3(.unlinkat, @as(usize, @bitCast(@as(isize, At.fdcwd))), @intFromPtr(path), 0);
} }
} }
@ -2237,24 +2237,24 @@ pub fn lstat(pathname: [*:0]const u8, statbuf: *Stat) usize {
} }
} }
pub fn fstatat(dirfd: i32, path: [*:0]const u8, stat_buf: *Stat, flags: u32) usize { pub fn fstatat(dirfd: i32, path: [*:0]const u8, stat_buf: *Stat, flags: At) usize {
if (native_arch == .riscv32 or native_arch.isLoongArch()) { if (native_arch == .riscv32 or native_arch.isLoongArch()) {
// riscv32 and loongarch have made the interesting decision to not implement some of // riscv32 and loongarch have made the interesting decision to not implement some of
// the older stat syscalls, including this one. // the older stat syscalls, including this one.
@compileError("No fstatat syscall on this architecture."); @compileError("No fstatat syscall on this architecture.");
} else if (@hasField(SYS, "fstatat64")) { } else if (@hasField(SYS, "fstatat64")) {
return syscall4(.fstatat64, @as(usize, @bitCast(@as(isize, dirfd))), @intFromPtr(path), @intFromPtr(stat_buf), flags); return syscall4(.fstatat64, @as(usize, @bitCast(@as(isize, dirfd))), @intFromPtr(path), @intFromPtr(stat_buf), @as(u32, @bitCast(flags)));
} else { } else {
return syscall4(.fstatat, @as(usize, @bitCast(@as(isize, dirfd))), @intFromPtr(path), @intFromPtr(stat_buf), flags); return syscall4(.fstatat, @as(usize, @bitCast(@as(isize, dirfd))), @intFromPtr(path), @intFromPtr(stat_buf), @as(u32, @bitCast(flags)));
} }
} }
pub fn statx(dirfd: i32, path: [*:0]const u8, flags: u32, mask: Statx.Mask, statx_buf: *Statx) usize { pub fn statx(dirfd: i32, path: [*:0]const u8, flags: At, mask: Statx.Mask, statx_buf: *Statx) usize {
return syscall5( return syscall5(
.statx, .statx,
@as(usize, @bitCast(@as(isize, dirfd))), @as(usize, @bitCast(@as(isize, dirfd))),
@intFromPtr(path), @intFromPtr(path),
flags, @intCast(@as(u32, @bitCast(flags))),
@intCast(@as(u32, @bitCast(mask))), @intCast(@as(u32, @bitCast(mask))),
@intFromPtr(statx_buf), @intFromPtr(statx_buf),
); );
@ -3476,6 +3476,7 @@ pub const STDIN_FILENO = 0;
pub const STDOUT_FILENO = 1; pub const STDOUT_FILENO = 1;
pub const STDERR_FILENO = 2; pub const STDERR_FILENO = 2;
pub const AT = At;
/// matches AT_* and AT_STATX_* /// matches AT_* and AT_STATX_*
pub const At = packed struct(u32) { pub const At = packed struct(u32) {
_reserved: u8 = 0, _reserved: u8 = 0,
@ -3485,7 +3486,10 @@ pub const At = packed struct(u32) {
/// Or /// Or
/// File handle is needed to compare object identity and may not be usable /// File handle is needed to compare object identity and may not be usable
/// with open_by_handle_at(2) /// with open_by_handle_at(2)
removedir_or_handle_fid: bool = false, removedir_or_handle_fid: packed union {
removedir: bool,
handle_fid: bool,
} = @bitCast(false),
/// Follow symbolic links. /// Follow symbolic links.
symlink_follow: bool = false, symlink_follow: bool = false,
/// Suppress terminal automount traversal /// Suppress terminal automount traversal
@ -3498,6 +3502,7 @@ pub const At = packed struct(u32) {
statx_dont_sync: bool = false, statx_dont_sync: bool = false,
/// Apply to the entire subtree /// Apply to the entire subtree
recursive: bool = false, recursive: bool = false,
_reserved_1: u16 = 0,
/// Special value used to indicate openat should use the current working directory /// Special value used to indicate openat should use the current working directory
pub const fdcwd = -100; pub const fdcwd = -100;
@ -3658,7 +3663,10 @@ pub const R_OK = 4;
pub const W = packed struct(u32) { pub const W = packed struct(u32) {
nohang: bool = false, nohang: bool = false,
untraced_or_stopped: bool = false, untraced_or_stopped: packed union {
untraced: bool,
stopped: bool,
} = @bitCast(false),
exited: bool = false, exited: bool = false,
continued: bool = false, continued: bool = false,
_unused: u20 = 0, _unused: u20 = 0,
@ -3885,12 +3893,21 @@ pub const SEEK = struct {
pub const END = 2; pub const END = 2;
}; };
pub const SHUT = struct { pub const SHUT = Shut;
pub const RD = 0; /// enum sock_shutdown_cmd - Shutdown types
pub const WR = 1; /// matches SHUT_* in kenel
pub const RDWR = 2; pub const Shut = enum(u32) {
/// SHUT_RD: shutdown receptions
rd = 0,
/// SHUT_WR: shutdown transmissions
wd = 1,
/// SHUT_RDWR: shutdown receptions/transmissions
rdwr = 2,
_,
}; };
pub const SOCK = Sock;
/// SOCK_* Socket type and flags /// SOCK_* Socket type and flags
pub const Sock = packed struct(u32) { pub const Sock = packed struct(u32) {
type: Type, type: Type,
@ -4031,109 +4048,64 @@ pub const UDP_ENCAP = struct {
pub const RXRPC = 6; pub const RXRPC = 6;
}; };
pub const PF = struct { /// Address Family
pub const UNSPEC = 0; pub const AF = enum(u16) {
pub const LOCAL = 1; unspec = 0,
pub const UNIX = LOCAL; unix = 1,
pub const FILE = LOCAL; inet = 2,
pub const INET = 2; ax25 = 3,
pub const AX25 = 3; ipx = 4,
pub const IPX = 4; appletalk = 5,
pub const APPLETALK = 5; netrom = 6,
pub const NETROM = 6; bridge = 7,
pub const BRIDGE = 7; atmpvc = 8,
pub const ATMPVC = 8; x25 = 9,
pub const X25 = 9; inet6 = 10,
pub const INET6 = 10; rose = 11,
pub const ROSE = 11; decnet = 12,
pub const DECnet = 12; netbeui = 13,
pub const NETBEUI = 13; security = 14,
pub const SECURITY = 14; key = 15,
pub const KEY = 15; route = 16,
pub const NETLINK = 16; packet = 17,
pub const ROUTE = PF.NETLINK; ash = 18,
pub const PACKET = 17; econet = 19,
pub const ASH = 18; atmsvc = 20,
pub const ECONET = 19; rds = 21,
pub const ATMSVC = 20; sna = 22,
pub const RDS = 21; irda = 23,
pub const SNA = 22; pppox = 24,
pub const IRDA = 23; wanpipe = 25,
pub const PPPOX = 24; llc = 26,
pub const WANPIPE = 25; ib = 27,
pub const LLC = 26; mpls = 28,
pub const IB = 27; can = 29,
pub const MPLS = 28; tipc = 30,
pub const CAN = 29; bluetooth = 31,
pub const TIPC = 30; iucv = 32,
pub const BLUETOOTH = 31; rxrpc = 33,
pub const IUCV = 32; isdn = 34,
pub const RXRPC = 33; phonet = 35,
pub const ISDN = 34; ieee802154 = 36,
pub const PHONET = 35; caif = 37,
pub const IEEE802154 = 36; alg = 38,
pub const CAIF = 37; nfc = 39,
pub const ALG = 38; vsock = 40,
pub const NFC = 39; kcm = 41,
pub const VSOCK = 40; qipcrtr = 42,
pub const KCM = 41; smc = 43,
pub const QIPCRTR = 42; xdp = 44,
pub const SMC = 43; max = 45,
pub const XDP = 44; _,
pub const MAX = 45;
// Aliases
pub const local = AF.unix;
pub const file = AF.unix;
pub const netlink = AF.route;
}; };
pub const AF = struct { /// Protocol Family (same values as Protocol Family)
pub const UNSPEC = PF.UNSPEC; pub const PF = AF;
pub const LOCAL = PF.LOCAL;
pub const UNIX = AF.LOCAL;
pub const FILE = AF.LOCAL;
pub const INET = PF.INET;
pub const AX25 = PF.AX25;
pub const IPX = PF.IPX;
pub const APPLETALK = PF.APPLETALK;
pub const NETROM = PF.NETROM;
pub const BRIDGE = PF.BRIDGE;
pub const ATMPVC = PF.ATMPVC;
pub const X25 = PF.X25;
pub const INET6 = PF.INET6;
pub const ROSE = PF.ROSE;
pub const DECnet = PF.DECnet;
pub const NETBEUI = PF.NETBEUI;
pub const SECURITY = PF.SECURITY;
pub const KEY = PF.KEY;
pub const NETLINK = PF.NETLINK;
pub const ROUTE = PF.ROUTE;
pub const PACKET = PF.PACKET;
pub const ASH = PF.ASH;
pub const ECONET = PF.ECONET;
pub const ATMSVC = PF.ATMSVC;
pub const RDS = PF.RDS;
pub const SNA = PF.SNA;
pub const IRDA = PF.IRDA;
pub const PPPOX = PF.PPPOX;
pub const WANPIPE = PF.WANPIPE;
pub const LLC = PF.LLC;
pub const IB = PF.IB;
pub const MPLS = PF.MPLS;
pub const CAN = PF.CAN;
pub const TIPC = PF.TIPC;
pub const BLUETOOTH = PF.BLUETOOTH;
pub const IUCV = PF.IUCV;
pub const RXRPC = PF.RXRPC;
pub const ISDN = PF.ISDN;
pub const PHONET = PF.PHONET;
pub const IEEE802154 = PF.IEEE802154;
pub const CAIF = PF.CAIF;
pub const ALG = PF.ALG;
pub const NFC = PF.NFC;
pub const VSOCK = PF.VSOCK;
pub const KCM = PF.KCM;
pub const QIPCRTR = PF.QIPCRTR;
pub const SMC = PF.SMC;
pub const XDP = PF.XDP;
pub const MAX = PF.MAX;
};
pub const SO = if (is_mips) struct { pub const SO = if (is_mips) struct {
pub const DEBUG = 1; pub const DEBUG = 1;
@ -5891,7 +5863,7 @@ pub const signalfd_siginfo = extern struct {
}; };
pub const in_port_t = u16; pub const in_port_t = u16;
pub const sa_family_t = u16; pub const sa_family_t = AF;
pub const socklen_t = u32; pub const socklen_t = u32;
pub const sockaddr = extern struct { pub const sockaddr = extern struct {
@ -7164,40 +7136,45 @@ pub const AI = packed struct(u32) {
pub const IPPORT_RESERVED = 1024; pub const IPPORT_RESERVED = 1024;
pub const IPPROTO = struct { /// IP Protocol numbers
pub const IP = 0; pub const IpProto = enum(u16) {
pub const HOPOPTS = 0; ip = 0,
pub const ICMP = 1; icmp = 1,
pub const IGMP = 2; igmp = 2,
pub const IPIP = 4; ipip = 4,
pub const TCP = 6; tcp = 6,
pub const EGP = 8; egp = 8,
pub const PUP = 12; pup = 12,
pub const UDP = 17; udp = 17,
pub const IDP = 22; idp = 22,
pub const TP = 29; tp = 29,
pub const DCCP = 33; dccp = 33,
pub const IPV6 = 41; ipv6 = 41,
pub const ROUTING = 43; routing = 43,
pub const FRAGMENT = 44; fragment = 44,
pub const RSVP = 46; rsvp = 46,
pub const GRE = 47; gre = 47,
pub const ESP = 50; esp = 50,
pub const AH = 51; ah = 51,
pub const ICMPV6 = 58; icmpv6 = 58,
pub const NONE = 59; none = 59,
pub const DSTOPTS = 60; dstopts = 60,
pub const MTP = 92; mtp = 92,
pub const BEETPH = 94; beetph = 94,
pub const ENCAP = 98; encap = 98,
pub const PIM = 103; pim = 103,
pub const COMP = 108; comp = 108,
pub const SCTP = 132; sctp = 132,
pub const MH = 135; mh = 135,
pub const UDPLITE = 136; udplite = 136,
pub const MPLS = 137; mpls = 137,
pub const RAW = 255; raw = 255,
pub const MAX = 256; max = 256,
_,
// Aliases
pub const hopopts = IpProto.ip;
pub const default = IpProto.ip;
}; };
pub const tcp_repair_opt = extern struct { pub const tcp_repair_opt = extern struct {

View file

@ -969,7 +969,7 @@ pub fn shutdown(
self: *IoUring, self: *IoUring,
user_data: u64, user_data: u64,
sockfd: posix.socket_t, sockfd: posix.socket_t,
how: linux.At, how: linux.Shut,
) !*Sqe { ) !*Sqe {
const sqe = try self.get_sqe(); const sqe = try self.get_sqe();
sqe.prep_shutdown(sockfd, how); sqe.prep_shutdown(sockfd, how);
@ -1330,7 +1330,8 @@ pub fn socket(
user_data: u64, user_data: u64,
domain: linux.AF, domain: linux.AF,
socket_type: linux.Sock, socket_type: linux.Sock,
protocol: u32, protocol: linux.IpProto,
/// flags is unused
flags: u32, flags: u32,
) !*Sqe { ) !*Sqe {
const sqe = try self.get_sqe(); const sqe = try self.get_sqe();
@ -1344,9 +1345,10 @@ pub fn socket(
pub fn socket_direct( pub fn socket_direct(
self: *IoUring, self: *IoUring,
user_data: u64, user_data: u64,
domain: u32, domain: linux.AF,
socket_type: u32, socket_type: linux.Sock,
protocol: u32, protocol: linux.IpProto,
/// flags is unused
flags: u32, flags: u32,
file_index: u32, file_index: u32,
) !*Sqe { ) !*Sqe {
@ -2432,7 +2434,7 @@ test "statx" {
0xaaaaaaaa, 0xaaaaaaaa,
tmp.dir.fd, tmp.dir.fd,
path, path,
0, .{},
.{ .size = true }, .{ .size = true },
&buf, &buf,
); );
@ -2460,7 +2462,7 @@ test "statx" {
.flags = .{}, .flags = .{},
}, cqe); }, cqe);
try testing.expect(buf.mask & linux.STATX_SIZE == linux.STATX_SIZE); try testing.expect(buf.mask.size);
try testing.expectEqual(@as(u64, 6), buf.size); try testing.expectEqual(@as(u64, 6), buf.size);
} }
@ -2618,7 +2620,8 @@ test "shutdown" {
// Socket bound, expect shutdown to work // Socket bound, expect shutdown to work
{ {
const server = try posix.socket(address.family, posix.SOCK.STREAM | posix.SOCK.CLOEXEC, 0); // TODO: update posix later to use Typed Flags
const server = try posix.socket(address.any.family, @as(u32, @bitCast(linux.Sock{ .type = .stream, .flags = .{ .cloexec = true } })), 0);
defer posix.close(server); defer posix.close(server);
try posix.setsockopt(server, posix.SOL.SOCKET, posix.SO.REUSEADDR, &mem.toBytes(@as(c_int, 1))); try posix.setsockopt(server, posix.SOL.SOCKET, posix.SO.REUSEADDR, &mem.toBytes(@as(c_int, 1)));
try posix.bind(server, addrAny(&address), @sizeOf(linux.sockaddr.in)); try posix.bind(server, addrAny(&address), @sizeOf(linux.sockaddr.in));
@ -2628,7 +2631,7 @@ test "shutdown" {
var slen: posix.socklen_t = @sizeOf(linux.sockaddr.in); var slen: posix.socklen_t = @sizeOf(linux.sockaddr.in);
try posix.getsockname(server, addrAny(&address), &slen); try posix.getsockname(server, addrAny(&address), &slen);
const shutdown_sqe = try ring.shutdown(0x445445445, server, linux.SHUT.RD); const shutdown_sqe = try ring.shutdown(0x445445445, server, .rd);
try testing.expectEqual(Op.SHUTDOWN, shutdown_sqe.opcode); try testing.expectEqual(Op.SHUTDOWN, shutdown_sqe.opcode);
try testing.expectEqual(@as(i32, server), shutdown_sqe.fd); try testing.expectEqual(@as(i32, server), shutdown_sqe.fd);
@ -2752,7 +2755,7 @@ test "unlinkat" {
0x12121212, 0x12121212,
tmp.dir.fd, tmp.dir.fd,
path, path,
0, .{},
); );
try testing.expectEqual(Op.UNLINKAT, sqe.opcode); try testing.expectEqual(Op.UNLINKAT, sqe.opcode);
try testing.expectEqual(@as(i32, tmp.dir.fd), sqe.fd); try testing.expectEqual(@as(i32, tmp.dir.fd), sqe.fd);
@ -2900,7 +2903,7 @@ test "linkat" {
first_path, first_path,
tmp.dir.fd, tmp.dir.fd,
second_path, second_path,
0, .{},
); );
try testing.expectEqual(Op.LINKAT, sqe.opcode); try testing.expectEqual(Op.LINKAT, sqe.opcode);
try testing.expectEqual(@as(i32, tmp.dir.fd), sqe.fd); try testing.expectEqual(@as(i32, tmp.dir.fd), sqe.fd);
@ -3651,7 +3654,7 @@ test "socket" {
defer ring.deinit(); defer ring.deinit();
// prepare, submit socket operation // prepare, submit socket operation
_ = try ring.socket(0, linux.AF.INET, posix.SOCK.STREAM, 0, 0); _ = try ring.socket(0, linux.AF.INET, .{ .type = .stream }, 0, 0);
try testing.expectEqual(@as(u32, 1), try ring.submit()); try testing.expectEqual(@as(u32, 1), try ring.submit());
// test completion // test completion
@ -3677,7 +3680,7 @@ test "socket_direct/socket_direct_alloc/close_direct" {
try ring.register_files(registered_fds[0..]); try ring.register_files(registered_fds[0..]);
// create socket in registered file descriptor at index 0 (last param) // create socket in registered file descriptor at index 0 (last param)
_ = try ring.socket_direct(0, linux.AF.INET, posix.SOCK.STREAM, 0, 0, 0); _ = try ring.socket_direct(0, .inet, .{ .type = .stream }, .default, 0, 0);
try testing.expectEqual(@as(u32, 1), try ring.submit()); try testing.expectEqual(@as(u32, 1), try ring.submit());
var cqe_socket = try ring.copy_cqe(); var cqe_socket = try ring.copy_cqe();
try testing.expectEqual(posix.E.SUCCESS, cqe_socket.err()); try testing.expectEqual(posix.E.SUCCESS, cqe_socket.err());
@ -4960,12 +4963,12 @@ pub const Sqe = extern struct {
sqe: *Sqe, sqe: *Sqe,
fd: linux.fd_t, fd: linux.fd_t,
path: [*:0]const u8, path: [*:0]const u8,
flags: linux.AT, flags: linux.At,
mask: linux.Statx.Mask, mask: linux.Statx.Mask,
buf: *linux.Statx, buf: *linux.Statx,
) void { ) void {
sqe.prep_rw(.STATX, fd, @intFromPtr(path), @bitCast(mask), @intFromPtr(buf)); sqe.prep_rw(.STATX, fd, @intFromPtr(path), @as(u32, @bitCast(mask)), @intFromPtr(buf));
sqe.rw_flags = flags; sqe.rw_flags = @bitCast(flags);
} }
pub fn prep_cancel( pub fn prep_cancel(
@ -5022,10 +5025,10 @@ pub const Sqe = extern struct {
sqe: *Sqe, sqe: *Sqe,
dir_fd: linux.fd_t, dir_fd: linux.fd_t,
path: [*:0]const u8, path: [*:0]const u8,
flags: linux.AT, // TODO: unlink flags only AT_REMOVEDIR flags: linux.At, // TODO: unlink flags only AT_REMOVEDIR
) void { ) void {
sqe.prep_rw(.UNLINKAT, dir_fd, @intFromPtr(path), 0, 0); sqe.prep_rw(.UNLINKAT, dir_fd, @intFromPtr(path), 0, 0);
sqe.rw_flags = flags; sqe.rw_flags = @bitCast(flags);
} }
pub fn prep_mkdirat( pub fn prep_mkdirat(
@ -5068,7 +5071,7 @@ pub const Sqe = extern struct {
@intFromPtr(new_path), @intFromPtr(new_path),
); );
sqe.len = @bitCast(new_dir_fd); sqe.len = @bitCast(new_dir_fd);
sqe.rw_flags = flags; sqe.rw_flags = @bitCast(flags);
} }
pub fn prep_files_update( pub fn prep_files_update(
@ -5114,7 +5117,8 @@ pub const Sqe = extern struct {
domain: linux.AF, domain: linux.AF,
socket_type: linux.SOCK, socket_type: linux.SOCK,
protocol: u32, // Enumerate https://github.com/kraj/musl/blob/kraj/master/src/network/proto.c#L7 protocol: u32, // Enumerate https://github.com/kraj/musl/blob/kraj/master/src/network/proto.c#L7
flags: u32, // flags is unused /// flags is unused
flags: u32,
) void { ) void {
sqe.prep_rw(.SOCKET, @intCast(domain), 0, protocol, socket_type); sqe.prep_rw(.SOCKET, @intCast(domain), 0, protocol, socket_type);
sqe.rw_flags = flags; sqe.rw_flags = flags;
@ -5123,9 +5127,10 @@ pub const Sqe = extern struct {
pub fn prep_socket_direct( pub fn prep_socket_direct(
sqe: *Sqe, sqe: *Sqe,
domain: linux.AF, domain: linux.AF,
socket_type: linux.SOCK, socket_type: linux.Sock,
protocol: u32, // Enumerate https://github.com/kraj/musl/blob/kraj/master/src/network/proto.c#L7 protocol: u32, // Enumerate https://github.com/kraj/musl/blob/kraj/master/src/network/proto.c#L7
flags: u32, // flags is unused /// flags is unused
flags: u32,
file_index: u32, file_index: u32,
) void { ) void {
prep_socket(sqe, domain, socket_type, protocol, flags); prep_socket(sqe, domain, socket_type, protocol, flags);

View file

@ -85,7 +85,7 @@ test "statx" {
defer file.close(); defer file.close();
var statx_buf: linux.Statx = undefined; var statx_buf: linux.Statx = undefined;
switch (linux.errno(linux.statx(file.handle, "", linux.AT.EMPTY_PATH, linux.Statx.Mask.basic_stats, &statx_buf))) { switch (linux.errno(linux.statx(file.handle, "", .{ .empty_path = true }, linux.Statx.Mask.basic_stats, &statx_buf))) {
.SUCCESS => {}, .SUCCESS => {},
else => unreachable, else => unreachable,
} }
@ -93,7 +93,7 @@ test "statx" {
if (builtin.cpu.arch == .riscv32 or builtin.cpu.arch.isLoongArch()) return error.SkipZigTest; // No fstatat, so the rest of the test is meaningless. if (builtin.cpu.arch == .riscv32 or builtin.cpu.arch.isLoongArch()) return error.SkipZigTest; // No fstatat, so the rest of the test is meaningless.
var stat_buf: linux.Stat = undefined; var stat_buf: linux.Stat = undefined;
switch (linux.errno(linux.fstatat(file.handle, "", &stat_buf, linux.AT.EMPTY_PATH))) { switch (linux.errno(linux.fstatat(file.handle, "", &stat_buf, .{ .empty_path = true }))) {
.SUCCESS => {}, .SUCCESS => {},
else => unreachable, else => unreachable,
} }