diff options
Diffstat (limited to 'src/pardes.zig')
| -rw-r--r-- | src/pardes.zig | 32 |
1 files changed, 30 insertions, 2 deletions
diff --git a/src/pardes.zig b/src/pardes.zig index 55461c5d..111e2853 100644 --- a/src/pardes.zig +++ b/src/pardes.zig @@ -3809,12 +3809,27 @@ pub const AttachRequest = struct { pane: u8, name: []const u8 }; /// freed the moment `off` reaches the end or the pane goes away. pub const PendingWrite = struct { bytes: []u8, off: usize = 0 }; +/// WHAT `pty/ctl`'s `sig` VERB CAN SEND. Named rather than numeric because the +/// core is freestanding: it has no `SIGINT` to name and a number written here +/// would be one platform's number travelling to a host that may not share it. +/// Five, and deliberately not the whole of signal(7): these are the ones a +/// human at a terminal already has a key or a `kill` for, and every one of +/// them means something to a program on a tty. `sig USR1` at a shell is a +/// message to a daemon, not a terminal operation, and nothing asked for it. +pub const PtySignal = enum(u8) { int, term, hup, quit, kill }; + /// IO the core wants done. Payloads are inline (fixed buffers): effects are /// queued values with no lifetime ties back into the core. pub const Effect = union(enum) { spawn: struct { pane: u8, cwd: Buf(256) }, write: struct { pane: u8, bytes: Buf(64) }, resize_pty: struct { pane: u8, cols: u16, rows: u16 }, + /// Deliver a signal to whatever is on this pane's tty — `pty/ctl`'s + /// `sig INT`, i.e. the ^C a script cannot type because ^C is not a byte + /// the pty would interpret on its own. The only genuinely new capability + /// the `pty/` directory added: `spawn` and `resize_pty` above were already + /// here, so `exec` and `winsize` are those two acquiring a name. + signal_pty: struct { pane: u8, sig: PtySignal }, open_link: Buf(256), /// write this pane's file content to its path; the shell reads both off /// the core (content is unbounded, effects are fixed-size values) @@ -6805,8 +6820,11 @@ pub const Pardes = struct { } /// Has a program taken this pane's tty? A host that cannot tell says no, - /// which is how pardes behaved before the probe existed. - fn hostTtyTaken(p: *const Pardes, id: usize) bool { + /// which is how pardes behaved before the probe existed. Public because + /// `pty/status` reports it: it is the one field of that file the core does + /// not own itself, and asking here rather than reaching for the vtable in + /// acmefs keeps the null-method default in one place. + pub fn hostTtyTaken(p: *const Pardes, id: usize) bool { const f = p.host.vtable.pull_tty_taken orelse return false; return f(p.host.ctx, @intCast(id)); } @@ -6857,6 +6875,10 @@ pub const Pardes = struct { // screen, and the bytes are dropped rather than transcribed. .write => |w| if (v.push_pty_write) |f| f(p.host.ctx, w.pane, w.bytes.slice()), .resize_pty => |r| if (v.push_pty_resize) |f| f(p.host.ctx, r.pane, r.cols, r.rows), + // A host with no signal method has no child to signal: the + // fallback host's ptys are silent (see `.write` above), so there + // is nothing to record and nothing to lie about. + .signal_pty => |s| if (v.push_pty_signal) |f| f(p.host.ctx, s.pane, s.sig), .open_link => |u| if (v.push_open_link) |f| f(p.host.ctx, u.slice()) else @@ -7081,6 +7103,12 @@ pub const Pardes = struct { }, .output => |o| { const pane = p.panes[o.pane] orelse return; + // The RAW bytes, before the emulator eats them. `pty/data`'s + // read is the only thing that wants them — the grid is a + // rendering and cannot be un-rendered — and this is one load + // and one branch on a pane nobody is reading. See + // `acmefs.notePtyOutput`. + acmefs.notePtyOutput(p, o.pane, o.bytes); term_pane.feedOutput(p, pane, o.bytes); }, .eof => |e| p.removePane(e.pane), |
