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.zig17
1 files changed, 15 insertions, 2 deletions
diff --git a/src/ninep/tree.zig b/src/ninep/tree.zig
index bc32ad33..c9e7b31a 100644
--- a/src/ninep/tree.zig
+++ b/src/ninep/tree.zig
@@ -122,6 +122,8 @@ pub const Open = struct {
event: bool,
/// The one open reading a pane's pty/data.
pty_data,
+ /// An open that may write a pane's ctl, and so hold its lock.
+ ctl,
} = .{ .snapshot = null },
/// A read that found nothing yet (`.again`), kept to be answered when
/// this open's file has something, the way factotum keeps its log's
@@ -141,7 +143,7 @@ pub const Open = struct {
.snapshot => |bytes| if (bytes) |b| gpa.free(b),
.log => |log| gpa.free(log.bytes),
.run => |run| gpa.free(run.output),
- .event, .pty_data => {},
+ .event, .pty_data, .ctl => {},
}
o.* = .{};
}
@@ -577,6 +579,10 @@ fn open(p: *Pardes, req: Req, target: Target) Reply {
.event => if (reader and pn.fs.event_reader) return failText(req.tag, E.BUSY, e_in_use) else .{ .event = reader },
.pty_data => if (!reader) return .{ .tag = req.tag } else if (pn.fs.pty_reader) return failText(req.tag, E.BUSY, e_in_use) else .pty_data,
.pty_run => .{ .run = .{} },
+ .ctl => switch (req.omode & 3) {
+ 1, 2 => .ctl, // OWRITE, ORDWR
+ else => return .{ .tag = req.tag },
+ },
else => return .{ .tag = req.tag },
};
},
@@ -605,7 +611,7 @@ fn open(p: *Pardes, req: Req, target: Target) Reply {
pn.fs.event_reader = pn.fs.event_reader or reader;
},
.pty_data => pane_of.?.fs.pty_reader = true,
- .run => {},
+ .run, .ctl => {},
}
return .{ .tag = req.tag, .handle = @intCast(i + 1) };
}
@@ -652,6 +658,13 @@ fn releaseHandle(p: *Pardes, req: Req) void {
.run => if (pn.fs.run == @as(u8, @intCast(req.handle - 1))) {
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))) {
+ pn.fs.lock = null;
+ pardes.turn.parked = true;
+ },
.snapshot, .log => {},
};
o.deinit(p.gpa);