diff options
Diffstat (limited to 'src/ninep/tree.zig')
| -rw-r--r-- | src/ninep/tree.zig | 26 |
1 files changed, 15 insertions, 11 deletions
diff --git a/src/ninep/tree.zig b/src/ninep/tree.zig index cc8f938a..9c3e1e9c 100644 --- a/src/ninep/tree.zig +++ b/src/ninep/tree.zig @@ -233,6 +233,9 @@ pub const TopFile = enum(u5) { /// The files opened lately, closed ones too, a line each: /// `open|closed <path>`, most recent first. recent, + /// `pardes -`'s: a directory written, its +Pager made or emptied; a + /// read of the same open answers its serial. + pager, pub fn fileName(f: TopFile) []const u8 { return if (f == .root) "/" else @tagName(f); @@ -241,7 +244,7 @@ pub const TopFile = enum(u5) { pub fn mode(f: TopFile) u16 { return switch (f) { .root, .pane, .col => 0o755, - .look, .exec, .log, .focus, .ctl, .tag, .tagexec => 0o666, + .look, .exec, .log, .focus, .ctl, .tag, .tagexec, .pager => 0o666, .README, .index, .status, .screen, .listeners, .new, .commands, .layout, .recent => 0o444, }; } @@ -645,7 +648,7 @@ fn topSize(p: *Pardes, f: TopFile) u64 { .tag => cols.headerText(p, null).?.len, .README => fs.help.len, .status => ctl.statusLen(p), - .look, .exec, .tagexec => ctl.resultsLen(p), + .look, .exec, .tagexec, .pager => ctl.resultsLen(p), // A stream: a length would read as its end to a kernel that caches // one (a 9ns mount's splice), and a follower's reads go past it. .log => 0, @@ -749,7 +752,7 @@ fn readdir(p: *Pardes, req: Req, target: Target) Reply { .root => { // The guide, then what describes the session, then the // files that act, then the directories. - inline for (.{ TopFile.README, TopFile.index, TopFile.status, TopFile.focus, TopFile.ctl, TopFile.commands, TopFile.recent, TopFile.look, TopFile.exec, TopFile.log, TopFile.screen, TopFile.listeners, TopFile.layout, TopFile.tag, TopFile.tagexec, TopFile.pane, TopFile.col }) |t| { + inline for (.{ TopFile.README, TopFile.index, TopFile.status, TopFile.focus, TopFile.ctl, TopFile.commands, TopFile.recent, TopFile.look, TopFile.exec, TopFile.pager, TopFile.log, TopFile.screen, TopFile.listeners, TopFile.layout, TopFile.tag, TopFile.tagexec, TopFile.pane, TopFile.col }) |t| { if (skip > 0) skip -= 1 else stageDirent(out, p.gpa, @intFromEnum(t), t.dir(), t.fileName()); } if (skip > 0) skip -= 1 else stageDirent(out, p.gpa, fs.os_root, true, "os"); @@ -1066,7 +1069,7 @@ fn readFile(p: *Pardes, req: Req, target: Target) Reply { break :index stagedReply(p, req); }, .status => ctl.readStatus(p, req), - .look, .exec, .tagexec => ctl.readResults(p, req), + .look, .exec, .tagexec, .pager => ctl.readResults(p, req), .log => events.readLog(p, req), .screen => screen.readSnapshot(p, req, null), .listeners => screen.readListeners(p, req), @@ -1125,7 +1128,7 @@ fn readFile(p: *Pardes, req: Req, target: Target) Reply { /// The files whose writes are lines of commands, run as each line is whole. fn linesFile(target: Target) bool { return switch (target) { - .top => |f| f == .look or f == .exec or f == .ctl or f == .tagexec, + .top => |f| f == .look or f == .exec or f == .ctl or f == .tagexec or f == .pager, .col => |c| c.file == .ctl or c.file == .exec, // `name` too: one name, however its writes cut it, applied once // its newline comes, or with its write when that is whole. @@ -1136,7 +1139,7 @@ fn linesFile(target: Target) bool { /// The ones of those a read answers with the panes a write touched. fn resultsFile(target: Target) bool { return switch (target) { - .top => |f| f == .look or f == .exec or f == .tagexec, + .top => |f| f == .look or f == .exec or f == .tagexec or f == .pager, .col => |c| c.file == .exec, .pane => |t| t.file == .look or t.file == .exec or t.file == .tagexec, }; @@ -1225,6 +1228,7 @@ fn writeNow(p: *Pardes, req: Req, target: Target) Reply { .log => events.writeLog(p, req), .focus => ctl.writeFocus(p, req), .ctl => ctl.writeRoot(p, req), + .pager => ctl.writePager(p, req), .tag => cols.write(p, req, null), .tagexec => cols.writeExec(p, req, null), else => Reply.fail(req.tag, E.PERM), @@ -1420,13 +1424,13 @@ test "readdir lists the root and a pane directory without creating anything" { @memcpy(top_bytes[0..top_reply.bytes.len], top_reply.bytes); const top = th.dirents(top_bytes[0..top_reply.bytes.len], &buf); try testing.expect(top.len >= 10); - for ([_][]const u8{ "README", "index", "status", "focus", "ctl", "commands", "recent", "look", "exec", "log", "screen", "listeners", "layout", "tag", "tagexec", "pane", "col", "os" }, 0..) |name, i| { + for ([_][]const u8{ "README", "index", "status", "focus", "ctl", "commands", "recent", "look", "exec", "pager", "log", "screen", "listeners", "layout", "tag", "tagexec", "pane", "col", "os" }, 0..) |name, i| { try testing.expectEqualStrings(name, top[i].name); - try testing.expectEqual(i >= 15, top[i].dir); + try testing.expectEqual(i >= 16, top[i].dir); } - try testing.expectEqual(@intFromEnum(TopFile.pane), top[15].node); - try testing.expectEqual(@intFromEnum(TopFile.col), top[16].node); - try testing.expectEqual(fs.os_root, top[17].node); + try testing.expectEqual(@intFromEnum(TopFile.pane), top[16].node); + try testing.expectEqual(@intFromEnum(TopFile.col), top[17].node); + try testing.expectEqual(fs.os_root, top[18].node); var idbuf: [16]u8 = undefined; try testing.expect(th.nameAt(top, try std.fmt.bufPrint(&idbuf, "{d}", .{serial})) == null); try testing.expect(th.nameAt(top, "self") == null); |
