diff options
| -rw-r--r-- | docs/fs.md | 2 | ||||
| -rw-r--r-- | src/ninep/events.zig | 23 |
2 files changed, 20 insertions, 5 deletions
@@ -549,7 +549,7 @@ text, which may hold newlines. its text (`FX0 0 1 6 Msg hi`). Write a record back to have it done as the click would: `<o><a><q0> <q1>\n` -acts on that range; the whole record as read acts on its text (the only way +acts on that range (the last record of a write needs no newline); the whole record as read acts on its text (the only way for `0 0`). A chorded record with its two follow-ups, in one write or three, runs once with its argument. `I`, `D`, `i`, `d` are refused. A helper holding `event` that writes its own pane's `exec` gets its command back as a diff --git a/src/ninep/events.zig b/src/ninep/events.zig index c6505f52..63405781 100644 --- a/src/ninep/events.zig +++ b/src/ninep/events.zig @@ -688,8 +688,17 @@ fn scanNumber(data: []const u8, i: *usize) ?u32 { } /// Writing a Look or Exec record back performs the action it names. -pub fn writeEvent(p: *Pardes, req: Req, id: usize) Reply { - const pane0 = p.panes[id] orelse return Reply.fail(req.tag, E.NOENT); +pub fn writeEvent(p: *Pardes, asked: Req, id: usize) Reply { + const pane0 = p.panes[id] orelse return Reply.fail(asked.tag, E.NOENT); + // Its last record needs no newline, as every other line file's last + // line does not (`printf 'MX0 10' > event`). + var req = asked; + if (req.data.len > 0 and req.data[req.data.len - 1] != '\n') { + const whole = p.scratch.allocator().alloc(u8, req.data.len + 1) catch return Reply.fail(req.tag, E.NOMEM); + @memcpy(whole[0..req.data.len], req.data); + whole[req.data.len] = '\n'; + req.data = whole; + } const serial = pane0.serial; { const body = pane_files.bodyOf(pane0); @@ -783,7 +792,7 @@ pub fn writeEvent(p: *Pardes, req: Req, id: usize) Reply { else => unreachable, } } - return .{ .tag = req.tag, .written = @intCast(req.data.len) }; + return .{ .tag = req.tag, .written = @intCast(asked.data.len) }; } // ---- tests ---- @@ -984,11 +993,17 @@ test "writing an event record back performs the action it names" { try testing.expectEqual(Status.ok, wr(p, event, "FX0 10\nFX0 10\n").reply.status); try testing.expectEqualStrings("fs-ran", pane.msg[0..pane.msg_len]); + // The last record needs no newline, as any line file's last line. + pane.msg_len = 0; + const bare = wr(p, event, "FX0 10"); + try testing.expectEqual(Status.ok, bare.reply.status); + try testing.expectEqual(@as(u32, 6), bare.reply.written); + try testing.expectEqualStrings("fs-ran", pane.msg[0..pane.msg_len]); + pane.msg_len = 0; for ([_][]const u8{ "FX0 10\nFQ0 1\n", // unknown type character "FX0 999\n", // out of range - "FX0 10", // no newline "FX5 1\n", // q0 > q1 "FD0 3\n", // a report, not a request "F\n", |
