diff options
| author | Gabriel Schneider <[email protected]> | 2026-10-01 09:58:15 -0300 |
|---|---|---|
| committer | Gabriel Schneider <[email protected]> | 2026-10-01 10:36:27 -0300 |
| commit | 70881bb4edd15fe918ee5fed4ed3e8922bc7fc6a (patch) | |
| tree | 18d80a3172d054cd152f78f56d82150f914b81f2 /src/ninep/ctl.zig | |
| parent | caa8ed077e8b9b67d18f18b3ec46891bd8d310a7 (diff) | |
| download | pardes-70881bb4edd15fe918ee5fed4ed3e8922bc7fc6a.tar.gz pardes-70881bb4edd15fe918ee5fed4ed3e8922bc7fc6a.zip | |
A command or terminal pane refused for room is refused before anything is logged or answered of it, and a serial is never handed out twice
A command pane with no room logged `new N` and `run N ls`, was answered
to its exec, then went with `del N` and no `exit N`; and sync gave N
back (`next_serial -= 1`) to the next pane made, so a script holding N
found another pane under it. Tty did the same. Both now take a refused
placement back at once, before the run is logged or the serial answered
(the pane was never announced, so it leaves no record), and fail the
write with no room. The decrement is gone: gaps are fine, and a serial
once said names one pane for good.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Diffstat (limited to 'src/ninep/ctl.zig')
| -rw-r--r-- | src/ninep/ctl.zig | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/src/ninep/ctl.zig b/src/ninep/ctl.zig index 40ffebc8..16fbabb4 100644 --- a/src/ninep/ctl.zig +++ b/src/ninep/ctl.zig @@ -4379,3 +4379,33 @@ test "a Mount dial with a network it does not know is a bad dial address, EINVAL try testing.expectEqual(E.INVAL, r.errno()); try testing.expectStringStartsWith(r.reply.ename, "Mount: bad dial address: nowhere!x"); } + +test "a command or a terminal refused for room is refused before anything is logged of it, and its serial is never handed out again" { + const p = try withFile(testing.allocator, "x\n"); + defer p.deinit(); + const exec = Node.of(serialOf(p), .exec); + var buf: [32]u8 = undefined; + for ([_][]const u8{ "ls\n", "Tty\n" }) |line| { + // Each a pane of its own until the column has no room for one more. + var before = p.next_serial; + var tries: usize = 0; + while (tries < pardes.MAX_PANES) : (tries += 1) { + before = p.next_serial; + const r = wr(p, exec, line); + p.sync(); + if (r.reply.status == .err) break; + } else return error.NeverRefused; + // Nothing said of the refused one: no new, no run, no del. + for (before + 1..p.next_serial + 1) |n| { + try testing.expect(!th.logHas(p, try std.fmt.bufPrint(&buf, "new {d} ", .{n}))); + try testing.expect(!th.logHas(p, try std.fmt.bufPrint(&buf, "run {d} ", .{n}))); + try testing.expect(!th.logHas(p, try std.fmt.bufPrint(&buf, "del {d} ", .{n}))); + } + // And the next pane made takes a serial past it. + const spent = p.next_serial; + p.update(.{ .resize = .{ .cols = 200, .rows = 200 } }); + const made = try th.newPane(p); + try testing.expect(made > spent); + p.update(.{ .resize = .{ .cols = 80, .rows = 24 } }); + } +} |
