summaryrefslogtreecommitdiff
path: root/src/ninep/tree.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/ninep/tree.zig')
-rw-r--r--src/ninep/tree.zig15
1 files changed, 11 insertions, 4 deletions
diff --git a/src/ninep/tree.zig b/src/ninep/tree.zig
index c9e7b31a..f93ab203 100644
--- a/src/ninep/tree.zig
+++ b/src/ninep/tree.zig
@@ -64,6 +64,7 @@ pub const e_bad_event = "bad event syntax";
/// A second open reading a file whose reads consume: rio's word for it
/// (windows/rio/xfid.c:25), which 9ns turns into EBUSY.
pub const e_in_use = "file in use";
+pub const e_shut_down = "window shut down";
fn reads(omode: u8) bool {
return omode & 3 != 1; // OWRITE is the one access mode that never reads
@@ -136,7 +137,7 @@ pub const Open = struct {
/// `asker` is the connection the read came on, which only the listener
/// knows.
- pub const Held = struct { asker: *anyopaque, req: Req };
+ pub const Held = struct { asker: *anyopaque, req: Req, ticket: cloud9.fs.Ticket };
pub fn deinit(o: *Open, gpa: std.mem.Allocator) void {
switch (o.what) {
@@ -655,13 +656,13 @@ fn releaseHandle(p: *Pardes, req: Req) void {
pn.fs.pty_out.clearAndFree(p.gpa);
},
// The command runs on in the shell; nobody is waiting for it any more.
- .run => if (pn.fs.run == @as(u8, @intCast(req.handle - 1))) {
+ .run => if (pn.fs.run == req.handle) {
pn.fs.run = null;
},
// Closing the open that holds the lock gives it up, as acme's clunk
// of its ctlfid does (editors/acme/xfid.c:211); a write parked on
// `lock` goes again.
- .ctl => if (pn.fs.lock == @as(u8, @intCast(req.handle - 1))) {
+ .ctl => if (pn.fs.lock == req.handle) {
pn.fs.lock = null;
pardes.turn.parked = true;
},
@@ -717,7 +718,13 @@ fn read(p: *Pardes, req: Req, target: Target) Reply {
.pane => |t| {
// A run's answer outlives the pane it ran in.
if (t.file == .pty_run and req.handle != 0) return pty.readRun(p, req);
- const id = p.paneBySerial(t.serial) orelse return Reply.fail(req.tag, E.NOENT);
+ const id = p.paneBySerial(t.serial) orelse {
+ // An event or pty/data read the pane closed under: acme's
+ // answer to the same (editors/acme/xfid.c:1005).
+ if (openOf(p, req)) |o| if (o.what == .event or o.what == .pty_data)
+ return failText(req.tag, E.IO, e_shut_down);
+ return Reply.fail(req.tag, E.NOENT);
+ };
const pn = p.panes[id].?;
if (t.file.inPty() and !pn.isTerminal()) return Reply.fail(req.tag, E.NOENT);
return pane.read(p, req, id, pn, t.file);