7225 lines · 250.9 KB · Zig
RawDownload
const std = @import("std");const builtin = @import("builtin");const contracts = @import("contracts.zig");const monitor_core = @import("monitor.zig");const terminal_engine = @import("engine.zig");const shell_resolver = @import("shell_resolver.zig");const terminal_store = @import("store.zig");const tmux_session = @import("tmux_session.zig");const host_capabilities = @import("../hosts/host.zig");const session_layout = @import("../session/session_layout.zig");const process_supervisor = @import("../background/process_supervisor.zig");const background_process_provider = @import(    "../execution/background_process_provider.zig",);const process_tree = @import("../execution/process_tree.zig");const command_admission = @import("../permissions/command_admission.zig");const sandbox = @import("../permissions/sandbox.zig");const execution_router = @import("../execution/router.zig");const io_mod = @import("../shared/io.zig");const debug_trace = @import("../shared/debug_trace.zig");const types = @import("../shared/types.zig");const workspace_pathing = @import("../workspace/pathing.zig"); const Allocator = std.mem.Allocator; const launcher_mode = "--fx-internal-terminal-launcher";const control_mode = "--fx-internal-terminal-control"; const max_sessions: usize = 16;const max_read_bytes: usize = 64 * 1024;const launcher_config_bytes: usize = contracts.max_command_bytes * 6 +    contracts.max_authority_text_bytes * 2 +    contracts.max_shell_path_bytes * 2 +    4096;const wait_poll_ns: u64 = 5 * std.time.ns_per_ms;const graceful_close_ms: i64 = 800;const control_poll_ms: i32 = 50;const marker_frame_timeout_ms: i64 = 5_000;const marker_ack_timeout_ms: i64 = tmux_session.marker_acknowledgement_timeout_ms;const command_release_byte: u8 = 2;const control_nonce_len: usize = 32;const marker_frame_len: usize = control_nonce_len + 1;const private_file_permissions = std.Io.File.Permissions.fromMode(0o600);const default_dimensions: contracts.Dimensions = .{    .rows = 24,    .columns = 80,};const ioctl_set_controlling_terminal: c_int = switch (builtin.os.tag) {    .macos => 0x20007461,    .linux => @intCast(std.os.linux.T.IOCSCTTY),    else => 0,};const ioctl_set_window_size: c_int = switch (builtin.os.tag) {    .macos => @bitCast(@as(u32, 0x80087467)),    .linux => @intCast(std.os.linux.T.IOCSWINSZ),    else => 0,}; const control_frame_len: usize = 5;const ControlKind = enum(u8) {    prepared = 1,    shell_ready = 2,    command_started = 3,    command_exited = 4,    command_signal = 5,    startup_failed = 6,    invalid_term = 7,}; const StartupFailure = enum(u32) {    shell_unavailable = 1,    profile_failed = 2,    control_failed = 3,}; const MarkerKind = enum(u8) {    shell_ready = 1,    command_started = 2,}; const LauncherConfig = struct {    argv: []const []const u8,    cwd: []const u8,    dimensions: contracts.Dimensions,    control_path: []const u8,    control_nonce: []const u8,    bootstrap_path: []const u8,    bootstrap: []const u8,    command_path: ?[]const u8,    command: ?[]const u8,}; const LauncherWatchdog = struct {    child_pid: std.posix.pid_t,    done: std.atomic.Value(bool) = .init(false),    command_released: std.atomic.Value(bool) = .init(false),    host_closed: std.atomic.Value(bool) = .init(false),     fn run(self: *LauncherWatchdog) void {        var poll_fds = [_]std.posix.pollfd{.{            .fd = std.posix.STDIN_FILENO,            .events = std.posix.POLL.IN,            .revents = 0,        }};        while (!self.done.load(.acquire)) {            poll_fds[0].revents = 0;            _ = std.posix.poll(&poll_fds, control_poll_ms) catch {                self.host_closed.store(true, .release);                _ = std.c.kill(-self.child_pid, std.c.SIG.KILL);                return;            };            if (poll_fds[0].revents == 0) continue;            var byte: [1]u8 = undefined;            const count = std.posix.read(std.posix.STDIN_FILENO, &byte) catch 0;            if (count != 0) {                if (byte[0] == command_release_byte) {                    self.command_released.store(true, .release);                }                continue;            }            self.host_closed.store(true, .release);            if (!self.done.load(.acquire)) {                _ = std.c.kill(-self.child_pid, std.c.SIG.KILL);            }            return;        }    }}; const ControlPhase = enum {    awaiting_shell,    shell_ready,    command_started,}; const LauncherControl = struct {    server: *std.Io.net.Server,    control_path: []const u8,    bootstrap_path: []const u8,    nonce: []const u8,    command_path: ?[]const u8,    child_pid: std.posix.pid_t,    watchdog: *LauncherWatchdog,    done: std.atomic.Value(bool) = .init(false),    phase: ControlPhase = .awaiting_shell,    failed: bool = false,     fn run(self: *LauncherControl) void {        self.runInner() catch {            self.failed = true;        };    }     fn runInner(self: *LauncherControl) !void {        var poll_fds = [_]std.posix.pollfd{.{            .fd = self.server.socket.handle,            .events = std.posix.POLL.IN,            .revents = 0,        }};        while (!self.done.load(.acquire)) {            poll_fds[0].revents = 0;            _ = try std.posix.poll(&poll_fds, control_poll_ms);            if (poll_fds[0].revents == 0) continue;             var stream = self.server.accept(io_mod.getIo()) catch |err| switch (err) {                error.ConnectionAborted, error.WouldBlock => continue,                else => return err,            };            defer stream.close(io_mod.getIo());            var bytes: [marker_frame_len]u8 = undefined;            receiveSocketExact(                stream.socket,                &bytes,                marker_frame_timeout_ms,            ) catch continue;            if (!std.mem.eql(                u8,                self.nonce,                bytes[0..control_nonce_len],            )) continue;            const kind: MarkerKind = switch (bytes[control_nonce_len]) {                1 => .shell_ready,                2 => .command_started,                else => continue,            };            if (!try self.acceptMarker(kind)) continue;            const finished = self.phase == .command_started or                (self.phase == .shell_ready and self.command_path == null);            if (finished) {                std.Io.Dir.deleteFileAbsolute(                    io_mod.getIo(),                    self.control_path,                ) catch {};            }            try writeAllFd(stream.socket.handle, &.{1}, false);            if (finished) {                return;            }        }    }     fn acceptMarker(        self: *LauncherControl,        kind: MarkerKind,    ) !bool {        switch (kind) {            .shell_ready => {                if (self.phase != .awaiting_shell) return false;                setEcho(std.posix.STDOUT_FILENO, true) catch {};                std.Io.Dir.deleteFileAbsolute(                    io_mod.getIo(),                    self.bootstrap_path,                ) catch {};                try writeControlFd(                    std.posix.STDERR_FILENO,                    .shell_ready,                    @intCast(self.child_pid),                );                self.phase = .shell_ready;            },            .command_started => {                if (self.phase != .shell_ready or                    self.command_path == null) return false;                std.Io.Dir.deleteFileAbsolute(                    io_mod.getIo(),                    self.command_path.?,                ) catch {};                try writeControlFd(                    std.posix.STDERR_FILENO,                    .command_started,                    @intCast(self.child_pid),                );                while (!self.watchdog.command_released.load(.acquire)) {                    if (self.watchdog.host_closed.load(.acquire)) {                        return error.LauncherHostClosed;                    }                    io_mod.sleep(wait_poll_ns);                }                self.phase = .command_started;            },        }        return true;    }}; pub const WorkTracker = struct {    context: ?*anyopaque,    update_fn: *const fn (?*anyopaque, bool) void,    monitor_update_fn: ?*const fn (?*anyopaque, bool) void = null,     fn update(self: WorkTracker, live: bool) void {        self.update_fn(self.context, live);    }     fn updateMonitor(self: WorkTracker, required: bool) void {        const callback = self.monitor_update_fn orelse return;        callback(self.context, required);    }}; fn isSupported() bool {    return isSupportedForOs(builtin.os.tag);} fn isSupportedForOs(os_tag: std.Target.Os.Tag) bool {    return host_capabilities.terminalSupportForOs(os_tag).isSupported();} test "native terminal backend selection follows canonical platform support" {    const os_tags = [_]std.Target.Os.Tag{        .macos,        .linux,        .windows,        .wasi,        .freebsd,        .emscripten,    };    for (os_tags) |os_tag| {        try std.testing.expectEqual(            host_capabilities.terminalSupportForOs(os_tag).isSupported(),            isSupportedForOs(os_tag),        );    }    try std.testing.expectEqual(isSupportedForOs(builtin.os.tag), isSupported());    const ExpectedRegistry = if (comptime host_capabilities        .terminalSupportForOs(builtin.os.tag)        .isSupported())        SupportedRegistry    else        UnsupportedRegistry;    try std.testing.expectEqualStrings(        @typeName(ExpectedRegistry),        @typeName(Registry),    );} pub fn isLauncherModeRaw(raw_args: []const [*:0]const u8) bool {    return raw_args.len == 2 and        std.mem.eql(u8, std.mem.sliceTo(raw_args[1], 0), launcher_mode);} pub fn isControlModeRaw(raw_args: []const [*:0]const u8) bool {    return raw_args.len == 5 and        std.mem.eql(u8, std.mem.sliceTo(raw_args[1], 0), control_mode);} pub fn runControlMarker(raw_args: []const [*:0]const u8) !void {    if (comptime !isSupported()) return error.TerminalHostUnsupported;    if (!isControlModeRaw(raw_args)) return error.InvalidControlMarker;    const control_path = std.mem.sliceTo(raw_args[2], 0);    const nonce = std.mem.sliceTo(raw_args[3], 0);    const event = std.mem.sliceTo(raw_args[4], 0);    if (nonce.len != control_nonce_len) return error.InvalidControlMarker;    const kind: MarkerKind =        if (std.mem.eql(u8, event, "shell-ready"))            .shell_ready        else if (std.mem.eql(u8, event, "command-started"))            .command_started        else            return error.InvalidControlMarker;     const tmux_failure = if (std.mem.startsWith(        u8,        control_path,        "/tmp/fx-tmux-marker-",    ))        io_mod.getenv("FX_TERMINAL_TEST_TMUX_MARKER_FAILURE")    else        null;    if (tmux_failure) |failure| {        if (std.mem.eql(u8, failure, "child-exit")) {            return error.InjectedTmuxMarkerChildExit;        }        if (std.mem.eql(u8, failure, "no-peer")) {            while (true) io_mod.sleep(wait_poll_ns);        }    }     var bytes: [marker_frame_len]u8 = @splat(0);    @memcpy(bytes[0..control_nonce_len], nonce);    bytes[control_nonce_len] = @intFromEnum(kind);    const address = try std.Io.net.UnixAddress.init(control_path);    var stream = try address.connect(io_mod.getIo());    defer stream.close(io_mod.getIo());    if (tmux_failure) |failure| {        if (std.mem.eql(u8, failure, "silent-peer")) {            while (true) io_mod.sleep(wait_poll_ns);        }        if (std.mem.eql(u8, failure, "partial-marker")) {            try writeAllFd(                stream.socket.handle,                bytes[0 .. bytes.len / 2],                false,            );            while (true) io_mod.sleep(wait_poll_ns);        }        if (std.mem.eql(u8, failure, "invalid-nonce")) {            bytes[0] ^= 1;            try writeAllFd(stream.socket.handle, &bytes, false);            while (true) io_mod.sleep(wait_poll_ns);        }    }    try writeAllFd(stream.socket.handle, &bytes, false);    var ack: [1]u8 = undefined;    try receiveSocketExact(stream.socket, &ack, marker_ack_timeout_ms);    if (ack[0] != 1) return error.ControlMarkerRejected;} fn writePrivateLauncherFile(path: []const u8, bytes: []const u8) !void {    var file = try std.Io.Dir.createFileAbsolute(        io_mod.getIo(),        path,        .{            .exclusive = true,            .permissions = private_file_permissions,        },    );    errdefer std.Io.Dir.deleteFileAbsolute(io_mod.getIo(), path) catch {};    defer file.close(io_mod.getIo());    try file.writeStreamingAll(io_mod.getIo(), bytes);} pub fn runLauncher(alloc: Allocator) !void {    if (comptime !isSupported()) return error.TerminalHostUnsupported;     var length_bytes: [4]u8 = undefined;    try readExactFd(std.posix.STDIN_FILENO, &length_bytes);    const config_len = std.mem.readInt(u32, &length_bytes, .little);    if (config_len == 0 or config_len > launcher_config_bytes) {        return error.InvalidLauncherConfig;    }    const config_bytes = try alloc.alloc(u8, config_len);    defer alloc.free(config_bytes);    try readExactFd(std.posix.STDIN_FILENO, config_bytes);    var parsed = try std.json.parseFromSlice(        LauncherConfig,        alloc,        config_bytes,        .{ .allocate = .alloc_always },    );    defer parsed.deinit();    if (parsed.value.argv.len == 0) return error.InvalidLauncherConfig;    if (!std.fs.path.isAbsolute(parsed.value.cwd) or        !std.fs.path.isAbsolute(parsed.value.control_path) or        !std.fs.path.isAbsolute(parsed.value.bootstrap_path) or        parsed.value.control_nonce.len != control_nonce_len or        (parsed.value.command == null) != (parsed.value.command_path == null))    {        return error.InvalidLauncherConfig;    }    if (parsed.value.command_path) |path| {        if (!std.fs.path.isAbsolute(path)) return error.InvalidLauncherConfig;    }    try parsed.value.dimensions.validate();     var bootstrap_created = false;    defer if (bootstrap_created) {        std.Io.Dir.deleteFileAbsolute(            io_mod.getIo(),            parsed.value.bootstrap_path,        ) catch {};    };    try writePrivateLauncherFile(        parsed.value.bootstrap_path,        parsed.value.bootstrap,    );    bootstrap_created = true;    var command_created = false;    defer if (command_created) {        std.Io.Dir.deleteFileAbsolute(            io_mod.getIo(),            parsed.value.command_path.?,        ) catch {};    };    if (parsed.value.command) |command| {        try writePrivateLauncherFile(parsed.value.command_path.?, command);        command_created = true;    }    std.Io.Dir.deleteFileAbsolute(        io_mod.getIo(),        parsed.value.control_path,    ) catch {};    const address = try std.Io.net.UnixAddress.init(parsed.value.control_path);    var server = try address.listen(io_mod.getIo(), .{});    defer server.deinit(io_mod.getIo());    defer std.Io.Dir.deleteFileAbsolute(        io_mod.getIo(),        parsed.value.control_path,    ) catch {};    try std.Io.Dir.cwd().setFilePermissions(        io_mod.getIo(),        parsed.value.control_path,        private_file_permissions,        .{ .follow_symlinks = false },    );     if (std.c.setsid() < 0) return error.SessionCreationFailed;    if (std.c.ioctl(        std.posix.STDOUT_FILENO,        ioctl_set_controlling_terminal,        @as(c_int, 0),    ) < 0) return error.ControllingTerminalFailed;    try resizeFd(std.posix.STDOUT_FILENO, parsed.value.dimensions);    try writeControlFd(std.posix.STDERR_FILENO, .prepared, 0);     var release: [1]u8 = undefined;    try readExactFd(std.posix.STDIN_FILENO, &release);    if (release[0] != 1) return error.InvalidLauncherRelease;     const terminal_file = std.Io.File{        .handle = std.posix.STDOUT_FILENO,        .flags = .{ .nonblocking = false },    };    var child = std.process.spawn(io_mod.getIo(), .{        .argv = parsed.value.argv,        .stdin = .{ .file = terminal_file },        .stdout = .{ .file = terminal_file },        .stderr = .{ .file = terminal_file },        .cwd = .{ .path = parsed.value.cwd },        .pgid = 0,    }) catch {        try writeControlFd(            std.posix.STDERR_FILENO,            .startup_failed,            @intFromEnum(StartupFailure.shell_unavailable),        );        return;    };    var child_running = true;    errdefer if (child_running) child.kill(io_mod.getIo());    const child_pid = child.id orelse return error.ChildIdentityMissing;    if (tcsetpgrp(std.posix.STDOUT_FILENO, child_pid) != 0) {        return error.ForegroundProcessGroupFailed;    }    var watchdog = LauncherWatchdog{ .child_pid = child_pid };    var control = LauncherControl{        .server = &server,        .control_path = parsed.value.control_path,        .bootstrap_path = parsed.value.bootstrap_path,        .nonce = parsed.value.control_nonce,

Lines 1–500 of 7225.