summaryrefslogtreecommitdiff
path: root/src/ninep/events.zig
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-09-27 19:37:05 -0300
committerGabriel Schneider <[email protected]>2026-10-01 00:12:14 -0300
commit7f31e62b63a64cef3916aac21417b7b1414000aa (patch)
tree75ae00e196e7eff22fc4659b512b12ce81f10cf6 /src/ninep/events.zig
parent594970f18dee92308fd1554663cc408cda4d102c (diff)
downloadpardes-7f31e62b63a64cef3916aac21417b7b1414000aa.tar.gz
pardes-7f31e62b63a64cef3916aac21417b7b1414000aa.zip
pty/run answers with the command's output; pin cloud9 with 9ns concurrency and E.BUSY
The answer is now the header line (exit N, or exit N cut M when only the last 64 KiB were kept, or exit N cut when its start scrolled out of the history), then what the command printed: the screen text between its C and D marks, which the marks handler pins so scrolling keeps them. Also from review: a plain /log open honours its offset until follow is written, so tail -n and less work; whitespace-only run lines are refused. cloud9 is pinned at 82d8152c: 9ns keeps up to 32 requests in flight per mount so a waiting read no longer freezes the rest of it, and E.BUSY replaces the errno pardes spelled locally. Co-Authored-By: Claude Opus 5.5 <[email protected]>
Diffstat (limited to 'src/ninep/events.zig')
-rw-r--r--src/ninep/events.zig11
1 files changed, 8 insertions, 3 deletions
diff --git a/src/ninep/events.zig b/src/ninep/events.zig
index 20cdeda4..bd5fecf3 100644
--- a/src/ninep/events.zig
+++ b/src/ninep/events.zig
@@ -209,10 +209,12 @@ pub fn readLog(p: *Pardes, req: Req) Reply {
const frozen = slot.bytes orelse &.{};
const out = p.fs.stage(p.gpa);
if (!slot.follow or slot.pos < frozen.len) {
- const off = @min(slot.pos, frozen.len);
+ // Until `follow`, the frozen text is a file like any other: `tail -n`
+ // seeks near its end, `less` seeks back. After it, a stream.
+ const off = @min(if (slot.follow) slot.pos else req.off, frozen.len);
const len = @min(frozen.len - off, req.size);
out.appendSlice(p.gpa, frozen[off..][0..len]) catch return Reply.fail(req.tag, E.NOMEM);
- slot.pos += len;
+ slot.pos = off + len;
return .{ .tag = req.tag, .payload = .{ .staged = @intCast(len) } };
}
const q = &p.fs.log;
@@ -671,6 +673,8 @@ test "the log records whether or not anyone reads, and an open that follows wait
const past = call(p, .{ .tag = 3, .op = .read, .node = log, .handle = plain.reply.handle, .off = first.bytes.len, .size = 8192 });
try testing.expectEqual(Status.ok, past.reply.status);
try testing.expectEqual(@as(usize, 0), past.bytes.len);
+ const tail = call(p, .{ .tag = 3, .op = .read, .node = log, .handle = plain.reply.handle, .off = first.bytes.len - early_owned.len, .size = 8192 });
+ try testing.expectEqualStrings(early_owned, tail.bytes);
_ = call(p, .{ .tag = 4, .op = .release, .node = log, .handle = plain.reply.handle });
// `follow` on an open makes it wait past what it froze, one record a read.
@@ -680,7 +684,8 @@ test "the log records whether or not anyone reads, and an open that follows wait
try testing.expectEqual(Status.err, call(p, .{ .tag = 7, .op = .write, .node = log, .handle = fh, .data = "tail\n" }).reply.status);
try testing.expectEqual(Status.ok, call(p, .{ .tag = 8, .op = .write, .node = log, .handle = fh, .data = "follow\n" }).reply.status);
// A stream: after `echo follow >&3` a shell reads at offset 7, and gets
- // what comes next, not the frozen text from byte 7.
+ // what comes next, not the frozen text from byte 7. Before `follow` the
+ // offset is honoured, so `tail -n` works (checked below on `plain`).
const rdf = struct {
fn next(pp: *Pardes, node: u64, h: u32, off: u64) th.Answer {
return call(pp, .{ .tag = 9, .op = .read, .node = node, .handle = h, .off = off, .size = 8192 });