diff options
Diffstat (limited to 'src/ninep/pty.zig')
| -rw-r--r-- | src/ninep/pty.zig | 21 |
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 { |
