Commit 266c81322e
Changed files (1)
lib
std
lib/std/c/darwin.zig
@@ -203,47 +203,6 @@ pub extern "c" fn mach_timebase_info(tinfo: ?*mach_timebase_info_data) kern_retu
pub extern "c" fn malloc_size(?*const anyopaque) usize;
pub extern "c" fn posix_memalign(memptr: *?*anyopaque, alignment: usize, size: usize) c_int;
-pub const posix_spawnattr_t = *opaque {};
-pub const posix_spawn_file_actions_t = *opaque {};
-pub extern "c" fn posix_spawnattr_init(attr: *posix_spawnattr_t) c_int;
-pub extern "c" fn posix_spawnattr_destroy(attr: *posix_spawnattr_t) c_int;
-pub extern "c" fn posix_spawnattr_setflags(attr: *posix_spawnattr_t, flags: c_short) c_int;
-pub extern "c" fn posix_spawnattr_getflags(attr: *const posix_spawnattr_t, flags: *c_short) c_int;
-pub extern "c" fn posix_spawn_file_actions_init(actions: *posix_spawn_file_actions_t) c_int;
-pub extern "c" fn posix_spawn_file_actions_destroy(actions: *posix_spawn_file_actions_t) c_int;
-pub extern "c" fn posix_spawn_file_actions_addclose(actions: *posix_spawn_file_actions_t, filedes: fd_t) c_int;
-pub extern "c" fn posix_spawn_file_actions_addopen(
- actions: *posix_spawn_file_actions_t,
- filedes: fd_t,
- path: [*:0]const u8,
- oflag: c_int,
- mode: mode_t,
-) c_int;
-pub extern "c" fn posix_spawn_file_actions_adddup2(
- actions: *posix_spawn_file_actions_t,
- filedes: fd_t,
- newfiledes: fd_t,
-) c_int;
-pub extern "c" fn posix_spawn_file_actions_addinherit_np(actions: *posix_spawn_file_actions_t, filedes: fd_t) c_int;
-pub extern "c" fn posix_spawn_file_actions_addchdir_np(actions: *posix_spawn_file_actions_t, path: [*:0]const u8) c_int;
-pub extern "c" fn posix_spawn_file_actions_addfchdir_np(actions: *posix_spawn_file_actions_t, filedes: fd_t) c_int;
-pub extern "c" fn posix_spawn(
- pid: *pid_t,
- path: [*:0]const u8,
- actions: ?*const posix_spawn_file_actions_t,
- attr: ?*const posix_spawnattr_t,
- argv: [*:null]?[*:0]const u8,
- env: [*:null]?[*:0]const u8,
-) c_int;
-pub extern "c" fn posix_spawnp(
- pid: *pid_t,
- path: [*:0]const u8,
- actions: ?*const posix_spawn_file_actions_t,
- attr: ?*const posix_spawnattr_t,
- argv: [*:null]?[*:0]const u8,
- env: [*:null]?[*:0]const u8,
-) c_int;
-
pub extern "c" fn kevent64(
kq: c_int,
changelist: [*]const kevent64_s,
@@ -2176,18 +2135,6 @@ pub const E = enum(u16) {
_,
};
-pub fn getKernError(err: kern_return_t) KernE {
- return @intToEnum(KernE, @truncate(u32, @intCast(usize, err)));
-}
-
-pub fn unexpectedKernError(err: KernE) std.os.UnexpectedError {
- if (std.os.unexpected_error_tracing) {
- std.debug.print("unexpected errno: {d}\n", .{@enumToInt(err)});
- std.debug.dumpCurrentStackTrace(null);
- }
- return error.Unexpected;
-}
-
/// Kernel return values
pub const KernE = enum(u32) {
SUCCESS = 0,
@@ -3063,6 +3010,29 @@ pub const CPUFAMILY = enum(u32) {
_,
};
+pub const PT = struct {
+ pub const TRACE_ME = 0;
+ pub const READ_I = 1;
+ pub const READ_D = 2;
+ pub const READ_U = 3;
+ pub const WRITE_I = 4;
+ pub const WRITE_D = 5;
+ pub const WRITE_U = 6;
+ pub const CONTINUE = 7;
+ pub const KILL = 8;
+ pub const STEP = 9;
+ pub const DETACH = 11;
+ pub const SIGEXC = 12;
+ pub const THUPDATE = 13;
+ pub const ATTACHEXC = 14;
+ pub const FORCEQUOTA = 30;
+ pub const DENY_ATTACH = 31;
+};
+
+pub const caddr_t = ?[*]u8;
+
+pub extern "c" fn ptrace(request: c_int, pid: pid_t, addr: caddr_t, data: c_int) c_int;
+
pub const POSIX_SPAWN_RESETIDS = 0x0001;
pub const POSIX_SPAWN_SETPGROUP = 0x0002;
pub const POSIX_SPAWN_SETSIGDEF = 0x0004;
@@ -3074,26 +3044,283 @@ pub const POSIX_SPAWN_SETSID = 0x0400;
pub const _POSIX_SPAWN_RESLIDE = 0x0800;
pub const POSIX_SPAWN_CLOEXEC_DEFAULT = 0x4000;
-pub const PT_TRACE_ME = 0;
-pub const PT_READ_I = 1;
-pub const PT_READ_D = 2;
-pub const PT_READ_U = 3;
-pub const PT_WRITE_I = 4;
-pub const PT_WRITE_D = 5;
-pub const PT_WRITE_U = 6;
-pub const PT_CONTINUE = 7;
-pub const PT_KILL = 8;
-pub const PT_STEP = 9;
-pub const PT_DETACH = 11;
-pub const PT_SIGEXC = 12;
-pub const PT_THUPDATE = 13;
-pub const PT_ATTACHEXC = 14;
-pub const PT_FORCEQUOTA = 30;
-pub const PT_DENY_ATTACH = 31;
+pub const posix_spawnattr_t = *opaque {};
+pub const posix_spawn_file_actions_t = *opaque {};
+pub extern "c" fn posix_spawnattr_init(attr: *posix_spawnattr_t) c_int;
+pub extern "c" fn posix_spawnattr_destroy(attr: *posix_spawnattr_t) c_int;
+pub extern "c" fn posix_spawnattr_setflags(attr: *posix_spawnattr_t, flags: c_short) c_int;
+pub extern "c" fn posix_spawnattr_getflags(attr: *const posix_spawnattr_t, flags: *c_short) c_int;
+pub extern "c" fn posix_spawn_file_actions_init(actions: *posix_spawn_file_actions_t) c_int;
+pub extern "c" fn posix_spawn_file_actions_destroy(actions: *posix_spawn_file_actions_t) c_int;
+pub extern "c" fn posix_spawn_file_actions_addclose(actions: *posix_spawn_file_actions_t, filedes: fd_t) c_int;
+pub extern "c" fn posix_spawn_file_actions_addopen(
+ actions: *posix_spawn_file_actions_t,
+ filedes: fd_t,
+ path: [*:0]const u8,
+ oflag: c_int,
+ mode: mode_t,
+) c_int;
+pub extern "c" fn posix_spawn_file_actions_adddup2(
+ actions: *posix_spawn_file_actions_t,
+ filedes: fd_t,
+ newfiledes: fd_t,
+) c_int;
+pub extern "c" fn posix_spawn_file_actions_addinherit_np(actions: *posix_spawn_file_actions_t, filedes: fd_t) c_int;
+pub extern "c" fn posix_spawn_file_actions_addchdir_np(actions: *posix_spawn_file_actions_t, path: [*:0]const u8) c_int;
+pub extern "c" fn posix_spawn_file_actions_addfchdir_np(actions: *posix_spawn_file_actions_t, filedes: fd_t) c_int;
+pub extern "c" fn posix_spawn(
+ pid: *pid_t,
+ path: [*:0]const u8,
+ actions: ?*const posix_spawn_file_actions_t,
+ attr: ?*const posix_spawnattr_t,
+ argv: [*:null]?[*:0]const u8,
+ env: [*:null]?[*:0]const u8,
+) c_int;
+pub extern "c" fn posix_spawnp(
+ pid: *pid_t,
+ path: [*:0]const u8,
+ actions: ?*const posix_spawn_file_actions_t,
+ attr: ?*const posix_spawnattr_t,
+ argv: [*:null]?[*:0]const u8,
+ env: [*:null]?[*:0]const u8,
+) c_int;
+
+pub const PosixSpawn = struct {
+ const errno = std.os.errno;
+ const unexpectedErrno = std.os.unexpectedErrno;
+
+ pub const Error = error{
+ SystemResources,
+ InvalidFileDescriptor,
+ NameTooLong,
+ TooBig,
+ PermissionDenied,
+ InputOutput,
+ FileSystem,
+ FileNotFound,
+ InvalidExe,
+ NotDir,
+ FileBusy,
+ /// Returned when the child fails to execute either in the pre-exec() initialization step, or
+ /// when exec(3) is invoked.
+ ChildExecFailed,
+ } || std.os.UnexpectedError;
+
+ pub const Attr = struct {
+ attr: posix_spawnattr_t,
+
+ pub fn init() Error!Attr {
+ var attr: posix_spawnattr_t = undefined;
+ switch (errno(posix_spawnattr_init(&attr))) {
+ .SUCCESS => return Attr{ .attr = attr },
+ .NOMEM => return error.SystemResources,
+ .INVAL => unreachable,
+ else => |err| return unexpectedErrno(err),
+ }
+ }
-pub const caddr_t = ?[*]u8;
+ pub fn deinit(self: *Attr) void {
+ defer self.* = undefined;
+ switch (errno(posix_spawnattr_destroy(&self.attr))) {
+ .SUCCESS => return,
+ .INVAL => unreachable, // Invalid parameters.
+ else => unreachable,
+ }
+ }
-pub extern "c" fn ptrace(request: c_int, pid: pid_t, addr: caddr_t, data: c_int) c_int;
+ pub fn get(self: Attr) Error!u16 {
+ var flags: c_short = undefined;
+ switch (errno(posix_spawnattr_getflags(&self.attr, &flags))) {
+ .SUCCESS => return @bitCast(u16, flags),
+ .INVAL => unreachable,
+ else => |err| return unexpectedErrno(err),
+ }
+ }
+
+ pub fn set(self: *Attr, flags: u16) Error!void {
+ switch (errno(posix_spawnattr_setflags(&self.attr, @bitCast(c_short, flags)))) {
+ .SUCCESS => return,
+ .INVAL => unreachable,
+ else => |err| return unexpectedErrno(err),
+ }
+ }
+ };
+
+ pub const Actions = struct {
+ actions: posix_spawn_file_actions_t,
+
+ pub fn init() Error!Actions {
+ var actions: posix_spawn_file_actions_t = undefined;
+ switch (errno(posix_spawn_file_actions_init(&actions))) {
+ .SUCCESS => return Actions{ .actions = actions },
+ .NOMEM => return error.SystemResources,
+ .INVAL => unreachable,
+ else => |err| return unexpectedErrno(err),
+ }
+ }
+
+ pub fn deinit(self: *Actions) void {
+ defer self.* = undefined;
+ switch (errno(posix_spawn_file_actions_destroy(&self.actions))) {
+ .SUCCESS => return,
+ .INVAL => unreachable, // Invalid parameters.
+ else => unreachable,
+ }
+ }
+
+ pub fn open(self: *Actions, fd: fd_t, path: []const u8, flags: u32, mode: mode_t) Error!void {
+ const posix_path = try std.os.toPosixPath(path);
+ return self.openZ(fd, &posix_path, flags, mode);
+ }
+
+ pub fn openZ(self: *Actions, fd: fd_t, path: [*:0]const u8, flags: u32, mode: mode_t) Error!void {
+ switch (errno(posix_spawn_file_actions_addopen(&self.actions, fd, path, @bitCast(c_int, flags), mode))) {
+ .SUCCESS => return,
+ .BADF => return error.InvalidFileDescriptor,
+ .NOMEM => return error.SystemResources,
+ .NAMETOOLONG => return error.NameTooLong,
+ .INVAL => unreachable, // the value of file actions is invalid
+ else => |err| return unexpectedErrno(err),
+ }
+ }
+
+ pub fn close(self: *Actions, fd: fd_t) Error!void {
+ switch (errno(posix_spawn_file_actions_addclose(&self.actions, fd))) {
+ .SUCCESS => return,
+ .BADF => return error.InvalidFileDescriptor,
+ .NOMEM => return error.SystemResources,
+ .INVAL => unreachable, // the value of file actions is invalid
+ .NAMETOOLONG => unreachable,
+ else => |err| return unexpectedErrno(err),
+ }
+ }
+
+ pub fn dup2(self: *Actions, fd: fd_t, newfd: fd_t) Error!void {
+ switch (errno(posix_spawn_file_actions_adddup2(&self.actions, fd, newfd))) {
+ .SUCCESS => return,
+ .BADF => return error.InvalidFileDescriptor,
+ .NOMEM => return error.SystemResources,
+ .INVAL => unreachable, // the value of file actions is invalid
+ .NAMETOOLONG => unreachable,
+ else => |err| return unexpectedErrno(err),
+ }
+ }
+
+ pub fn inherit(self: *Actions, fd: fd_t) Error!void {
+ switch (errno(posix_spawn_file_actions_addinherit_np(&self.actions, fd))) {
+ .SUCCESS => return,
+ .BADF => return error.InvalidFileDescriptor,
+ .NOMEM => return error.SystemResources,
+ .INVAL => unreachable, // the value of file actions is invalid
+ .NAMETOOLONG => unreachable,
+ else => |err| return unexpectedErrno(err),
+ }
+ }
+
+ pub fn chdir(self: *Actions, path: []const u8) Error!void {
+ const posix_path = try std.os.toPosixPath(path);
+ return self.chdirZ(&posix_path);
+ }
+
+ pub fn chdirZ(self: *Actions, path: [*:0]const u8) Error!void {
+ switch (errno(posix_spawn_file_actions_addchdir_np(&self.actions, path))) {
+ .SUCCESS => return,
+ .NOMEM => return error.SystemResources,
+ .NAMETOOLONG => return error.NameTooLong,
+ .BADF => unreachable,
+ .INVAL => unreachable, // the value of file actions is invalid
+ else => |err| return unexpectedErrno(err),
+ }
+ }
+
+ pub fn fchdir(self: *Actions, fd: fd_t) Error!void {
+ switch (errno(posix_spawn_file_actions_addfchdir_np(&self.actions, fd))) {
+ .SUCCESS => return,
+ .BADF => return error.InvalidFileDescriptor,
+ .NOMEM => return error.SystemResources,
+ .INVAL => unreachable, // the value of file actions is invalid
+ .NAMETOOLONG => unreachable,
+ else => |err| return unexpectedErrno(err),
+ }
+ }
+ };
+
+ pub fn spawn(
+ path: []const u8,
+ actions: ?Actions,
+ attr: ?Attr,
+ argv: [*:null]?[*:0]const u8,
+ envp: [*:null]?[*:0]const u8,
+ ) Error!pid_t {
+ const posix_path = try std.os.toPosixPath(path);
+ return spawnZ(&posix_path, actions, attr, argv, envp);
+ }
+
+ pub fn spawnZ(
+ path: [*:0]const u8,
+ actions: ?Actions,
+ attr: ?Attr,
+ argv: [*:null]?[*:0]const u8,
+ envp: [*:null]?[*:0]const u8,
+ ) Error!pid_t {
+ var pid: pid_t = undefined;
+ switch (errno(posix_spawn(
+ &pid,
+ path,
+ if (actions) |a| &a.actions else null,
+ if (attr) |a| &a.attr else null,
+ argv,
+ envp,
+ ))) {
+ .SUCCESS => return pid,
+ .@"2BIG" => return error.TooBig,
+ .NOMEM => return error.SystemResources,
+ .BADF => return error.InvalidFileDescriptor,
+ .ACCES => return error.PermissionDenied,
+ .IO => return error.InputOutput,
+ .LOOP => return error.FileSystem,
+ .NAMETOOLONG => return error.NameTooLong,
+ .NOENT => return error.FileNotFound,
+ .NOEXEC => return error.InvalidExe,
+ .NOTDIR => return error.NotDir,
+ .TXTBSY => return error.FileBusy,
+ .BADARCH => return error.InvalidExe,
+ .BADEXEC => return error.InvalidExe,
+ .FAULT => unreachable,
+ .INVAL => unreachable,
+ else => |err| return unexpectedErrno(err),
+ }
+ }
+
+ pub fn waitpid(pid: pid_t, flags: u32) Error!std.os.WaitPidResult {
+ var status: c_int = undefined;
+ while (true) {
+ const rc = waitpid(pid, &status, @intCast(c_int, flags));
+ switch (errno(rc)) {
+ .SUCCESS => return std.os.WaitPidResult{
+ .pid = @intCast(pid_t, rc),
+ .status = @bitCast(u32, status),
+ },
+ .INTR => continue,
+ .CHILD => return error.ChildExecFailed,
+ .INVAL => unreachable, // Invalid flags.
+ else => unreachable,
+ }
+ }
+ }
+};
+
+pub fn getKernError(err: kern_return_t) KernE {
+ return @intToEnum(KernE, @truncate(u32, @intCast(usize, err)));
+}
+
+pub fn unexpectedKernError(err: KernE) std.os.UnexpectedError {
+ if (std.os.unexpected_error_tracing) {
+ std.debug.print("unexpected errno: {d}\n", .{@enumToInt(err)});
+ std.debug.dumpCurrentStackTrace(null);
+ }
+ return error.Unexpected;
+}
pub const MachError = error{
/// Not enough permissions held to perform the requested kernel