Created
January 9, 2023 19:15
-
-
Save matu3ba/0aa440e530ada8773714985f4518ab73 to your computer and use it in GitHub Desktop.
spawnMac changes for posix_spawn that I found no use case for yet: user owns the actions + attribute or users doesnt.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// Use this for additional posix spawn attributes. | |
/// Do not set spawn attribute flags and do not modify stdin, stdout, stderr | |
/// behavior, because those are set in the platform-specific spawn method. | |
posix_attr: if (os.hasPosixSpawn) ?os.posix_spawn.Attr else void, | |
posix_actions: if (os.hasPosixSpawn) ?os.posix_spawn.Actions else void, | |
.posix_attr = if (os.hasPosixSpawn) null else undefined, | |
.posix_actions = if (os.hasPosixSpawn) null else undefined, | |
fn spawnMacos(self: *ChildProcess) SpawnError!void { | |
// dont cleanup structure owned == initialized by user | |
const user_attr: bool = self.posix_attr != null; | |
const user_actions: bool = self.posix_actions != null; | |
const pipe_flags = if (io.is_async) os.O.NONBLOCK else 0; | |
const stdin_pipe = if (self.stdin_behavior == StdIo.Pipe) try os.pipe2(pipe_flags) else undefined; | |
errdefer if (self.stdin_behavior == StdIo.Pipe) destroyPipe(stdin_pipe); | |
const stdout_pipe = if (self.stdout_behavior == StdIo.Pipe) try os.pipe2(pipe_flags) else undefined; | |
errdefer if (self.stdout_behavior == StdIo.Pipe) destroyPipe(stdout_pipe); | |
const stderr_pipe = if (self.stderr_behavior == StdIo.Pipe) try os.pipe2(pipe_flags) else undefined; | |
errdefer if (self.stderr_behavior == StdIo.Pipe) destroyPipe(stderr_pipe); | |
const any_ignore = (self.stdin_behavior == StdIo.Ignore or self.stdout_behavior == StdIo.Ignore or self.stderr_behavior == StdIo.Ignore); | |
const dev_null_fd = if (any_ignore) | |
os.openZ("/dev/null", os.O.RDWR, 0) catch |err| switch (err) { | |
error.PathAlreadyExists => unreachable, | |
error.NoSpaceLeft => unreachable, | |
error.FileTooBig => unreachable, | |
error.DeviceBusy => unreachable, | |
error.FileLocksNotSupported => unreachable, | |
error.BadPathName => unreachable, // Windows-only | |
error.InvalidHandle => unreachable, // WASI-only | |
error.WouldBlock => unreachable, | |
else => |e| return e, | |
} | |
else | |
undefined; | |
defer if (any_ignore) os.close(dev_null_fd); | |
if (user_attr == false) self.posix_attr = try os.posix_spawn.Attr.init(); | |
defer if (user_attr == false) self.posix_attr.?.deinit(); | |
var flags: u16 = os.darwin.POSIX_SPAWN_SETSIGDEF | os.darwin.POSIX_SPAWN_SETSIGMASK; | |
if (self.disable_aslr) { | |
flags |= os.darwin._POSIX_SPAWN_DISABLE_ASLR; | |
} | |
if (self.start_suspended) { | |
flags |= os.darwin.POSIX_SPAWN_START_SUSPENDED; | |
} | |
try self.posix_attr.?.set(flags); | |
if (user_actions == false) self.posix_actions = try os.posix_spawn.Actions.init(); | |
defer if (user_actions == false) self.posix_actions.?.deinit(); | |
try setUpChildIoPosixSpawn(self.stdin_behavior, &self.posix_actions.?, stdin_pipe, os.STDIN_FILENO, dev_null_fd); | |
try setUpChildIoPosixSpawn(self.stdout_behavior, &self.posix_actions.?, stdout_pipe, os.STDOUT_FILENO, dev_null_fd); | |
try setUpChildIoPosixSpawn(self.stderr_behavior, &self.posix_actions.?, stderr_pipe, os.STDERR_FILENO, dev_null_fd); | |
if (self.cwd_dir) |cwd| { | |
try self.posix_actions.?.fchdir(cwd.fd); | |
} else if (self.cwd) |cwd| { | |
try self.posix_actions.?.chdir(cwd); | |
} | |
var arena_allocator = std.heap.ArenaAllocator.init(self.allocator); | |
defer arena_allocator.deinit(); | |
const arena = arena_allocator.allocator(); | |
const argv_buf = try arena.allocSentinel(?[*:0]u8, self.argv.len, null); | |
for (self.argv) |arg, i| argv_buf[i] = (try arena.dupeZ(u8, arg)).ptr; | |
const envp = if (self.env_map) |env_map| m: { | |
const envp_buf = try createNullDelimitedEnvMap(arena, env_map); | |
break :m envp_buf.ptr; | |
} else std.c.environ; | |
const pid = try os.posix_spawn.spawnp(self.argv[0], self.posix_actions.?, self.posix_attr.?, argv_buf, envp); | |
if (self.stdin_behavior == StdIo.Pipe) { | |
self.stdin = File{ .handle = stdin_pipe[1] }; | |
} else { | |
self.stdin = null; | |
} | |
if (self.stdout_behavior == StdIo.Pipe) { | |
self.stdout = File{ .handle = stdout_pipe[0] }; | |
} else { | |
self.stdout = null; | |
} | |
if (self.stderr_behavior == StdIo.Pipe) { | |
self.stderr = File{ .handle = stderr_pipe[0] }; | |
} else { | |
self.stderr = null; | |
} | |
self.pid = pid; | |
self.term = null; | |
if (self.stdin_behavior == StdIo.Pipe) { | |
os.close(stdin_pipe[0]); | |
} | |
if (self.stdout_behavior == StdIo.Pipe) { | |
os.close(stdout_pipe[1]); | |
} | |
if (self.stderr_behavior == StdIo.Pipe) { | |
os.close(stderr_pipe[1]); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment