diff options
| author | Gabriel Schneider <[email protected]> | 2026-10-01 05:10:37 -0300 |
|---|---|---|
| committer | Gabriel Schneider <[email protected]> | 2026-10-01 05:18:09 -0300 |
| commit | d378de9c497f46090a3d0d30508f504eae5cd48f (patch) | |
| tree | c8bc4bcc09836bd1062b9d7581de545b3fb6a112 /src/ninep/ctl.zig | |
| parent | c95f2703875880e583dfbce5ce19c38faa3d5b76 (diff) | |
| download | pardes-d378de9c497f46090a3d0d30508f504eae5cd48f.tar.gz pardes-d378de9c497f46090a3d0d30508f504eae5cd48f.zip | |
A pane ctl takes Tty+bash as exec and the tag do: a word that takes its argument after a + is no unknown control message there
checkBuiltin split a line at its first blank only, so `Tty+bash` was
one unknown word on a ctl while exec ran it. It now splits at the +
for the words whose registry entry says they take one so.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Diffstat (limited to 'src/ninep/ctl.zig')
| -rw-r--r-- | src/ninep/ctl.zig | 14 |
1 files changed, 13 insertions, 1 deletions
diff --git a/src/ninep/ctl.zig b/src/ninep/ctl.zig index 1e274e0c..b7c529e1 100644 --- a/src/ninep/ctl.zig +++ b/src/ninep/ctl.zig @@ -471,7 +471,11 @@ fn blanked(line: []const u8, buf: []u8) []const u8 { /// Answers the refusal, or null. Words are the builtins' own, capitalised /// as on a tag; acme's lowercase verbs are the pane ctl's and alias none. fn checkBuiltin(p: *Pardes, req: Req, line: []const u8, scope: builtins.Scope) ?Reply { - const sp = std.mem.indexOfAny(u8, line, " \t"); + var sp = std.mem.indexOfAny(u8, line, " \t"); + // `Word+arg` for a word that takes one so (`Tty+bash`), as exec does. + if (sp == null) if (std.mem.indexOfScalar(u8, line, '+')) |at| if (std.meta.stringToEnum(Builtin, line[0..at])) |head| { + if (builtins.registry.plusArg(head)) sp = at; + }; const typed = line[0 .. sp orelse line.len]; // acme's words: checked as the pardes word they run as, or refused. const word = for (pardes.exec.acme_words) |w| { @@ -4081,3 +4085,11 @@ test "a body write to an image pane says its body takes none, not that terminals doc.image = .{ .path = try p.gpa.dupe(u8, "/tmp/pardes-pic.ppm") }; try testing.expectEqualStrings(pane_files.e_no_body, wr(p, Node.of(doc.serial, .body), "x").reply.ename); } + +test "Tty+bash on a pane ctl is Tty with its argument, as exec and the tag take it" { + const p = try withFile(testing.allocator, "x\n"); + defer p.deinit(); + const r = call(p, .{ .tag = 1, .op = .write, .node = Node.of(serialOf(p), .ctl), .data = "Tty+sh\n" }); + try testing.expectEqual(Status.ok, r.reply.status); + try testing.expect(r.spawned); +} |
