summaryrefslogtreecommitdiff
path: root/src/ninep/pty.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/ninep/pty.zig')
-rw-r--r--src/ninep/pty.zig21
1 files changed, 16 insertions, 5 deletions
diff --git a/src/ninep/pty.zig b/src/ninep/pty.zig
index 936f9b73..49f52c82 100644
--- a/src/ninep/pty.zig
+++ b/src/ninep/pty.zig
@@ -164,7 +164,7 @@ pub fn writeRun(p: *Pardes, req: Req, id: usize, pane: *Pane) Reply {
const marks = &state.stream.handler;
if (pf.unmarked) {
answer(p, slot, "error no prompt marks", .{});
- } else if (pf.run != null or marks.phase != .input or
+ } else if (waitingRun(p, pane) != null or marks.phase != .input or
!pardes.panes.Terminal.promptInputEmpty(pane) or p.hostTtyTaken(id))
{
// Something is running, someone has typed at the prompt, or the
@@ -180,7 +180,7 @@ pub fn writeRun(p: *Pardes, req: Req, id: usize, pane: *Pane) Reply {
p.emitWrite(id, line);
p.emitWrite(id, "\r");
slot.phase = .sent;
- pf.run = @intCast(req.handle - 1);
+ pf.run = req.handle;
}
return .{ .tag = req.tag, .written = @intCast(req.data.len) };
}
@@ -217,7 +217,7 @@ pub fn noteMarks(p: *Pardes, id: usize, pane: *Pane) void {
if (comptime !pardes.panes.Terminal.enabled) return;
const state = pane.terminal orelse return;
const pf = &pane.fs;
- const slot = &p.fs.opens[pf.run orelse return].what.run;
+ const slot = waitingRun(p, pane) orelse return;
const marks = &state.stream.handler;
if (marks.phase != .input) return;
// ponytail: a prompt redrawn before the command starts (a resize in that
@@ -297,11 +297,22 @@ pub fn noteMarks(p: *Pardes, id: usize, pane: *Pane) void {
/// The pane closed or its shell was replaced: the command's end will never
/// be reported, so the run says so instead of waiting forever.
pub fn shellGone(p: *Pardes, pane: *Pane) void {
- const idx = pane.fs.run orelse return;
- answer(p, &p.fs.opens[idx].what.run, "error shell gone", .{});
+ answer(p, waitingRun(p, pane) orelse return, "error shell gone", .{});
pane.fs.run = null;
}
+/// The run waiting on this shell's command. The pane keeps its open's
+/// handle, which names that open only on the node it was opened on, so it
+/// is looked up the way a request's is; one that no longer names a run is
+/// forgotten.
+fn waitingRun(p: *Pardes, pane: *Pane) ?*Run {
+ const handle = pane.fs.run orelse return null;
+ if (tree.openOf(p, .{ .tag = 0, .op = .read, .node = tree.Node.of(pane.serial, .pty_run), .handle = handle })) |o|
+ if (o.what == .run) return &o.what.run;
+ pane.fs.run = null;
+ return null;
+}
+
const e_bad_line = "bad command line";
pub fn readData(p: *Pardes, req: Req, pf: *pane_files.State) Reply {