diff --git a/src/aio/common/posix.zig b/src/aio/common/posix.zig index 0629e86..db4a4a6 100644 --- a/src/aio/common/posix.zig +++ b/src/aio/common/posix.zig @@ -190,6 +190,7 @@ pub inline fn perform(op: anytype) Operation.Error!void { .mkdir_at => _ = try std.posix.mkdiratZ(op.dir.fd, op.path, op.mode), .symlink_at => _ = try std.posix.symlinkatZ(op.target, op.dir.fd, op.link_path), .child_exit => { + // TODO: prefer pidfd_wait and kevent instead, requires passing the `Readiness` to this function if (@hasDecl(std.posix.system, "waitid")) { _ = std.posix.system.waitid(.PID, op.child, @constCast(&op._), std.posix.W.EXITED); if (op.out_term) |term| { @@ -258,6 +259,23 @@ pub inline fn openReadiness(op: anytype) OpenReadinessError!Readiness { else => std.posix.unexpectedErrno(e), }; break :blk .{ .fd = @intCast(res), .mode = .in }; + } else if (comptime @hasDecl(std.posix.system, "kqueue")) { + const fd = try std.posix.kqueue(); + _ = std.posix.kevent(fd, &.{.{ + .ident = op.child, + .filter = std.posix.system.EVFILT_PROC, + .flags = std.posix.system.EV_ADD | std.posix.system.EV_ENABLE | std.posix.system.EV_ONESHOT, + .fflags = std.posix.system.NOTE_EXIT, + .data = 0, + .udata = 0, + }}, &.{}, null) catch |err| return switch (err) { + error.EventNotFound => unreachable, + error.ProcessNotFound => unreachable, + error.AccessDenied => unreachable, + error.SystemResources => |e| e, + else => error.Unexpected, + }; + break :blk .{ .fd = fd, .mode = .in }; } else { @panic("unsupported"); }