Skip to content

Instantly share code, notes, and snippets.

@matu3ba
Created January 9, 2023 19:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save matu3ba/0aa440e530ada8773714985f4518ab73 to your computer and use it in GitHub Desktop.
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.
/// 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