summaryrefslogtreecommitdiff
path: root/src/9p_io.zig
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-09-20 00:36:50 -0300
committerGabriel Schneider <[email protected]>2026-10-01 00:12:14 -0300
commitc1990b3e6e196ad41379aa432bf3ccca8a65d9f0 (patch)
treed7ad5afe559f7f56464b14c3122242fa3f16399b /src/9p_io.zig
parent717afaf3177a2e0925b18ae3445119efe808b129 (diff)
downloadpardes-c1990b3e6e196ad41379aa432bf3ccca8a65d9f0.tar.gz
pardes-c1990b3e6e196ad41379aa432bf3ccca8a65d9f0.zip
Flatten the 9P control tree and move it out of fs.zig
The served tree loses the self/ level: /index /ctl /new /log /screen /listeners /pane/<n>/... /os, with /src only in -Dembed-sources=true builds (default off, on for esp32p4). ctl speaks the editor's own language with two lowercase verbs, look TEXT and exec TEXT, plus acme's addr verbs; the new/ factory directory becomes one clone file; cons is gone (exec Msg); name and sel are files; stats report real lengths, modes and mtimes; /log streams pane new/del/rename/save events. The tree code lives in src/ninep/ (tree, pane, ctl, addr, pty, events, screen, sources); fs.zig keeps host access, mounts, resolution and find/grep. Same engine and transports. README (fs-help.txt) and docs rewritten; tests updated and extended. Co-Authored-By: Claude Fable 5.1 <[email protected]>
Diffstat (limited to 'src/9p_io.zig')
-rw-r--r--src/9p_io.zig39
1 files changed, 19 insertions, 20 deletions
diff --git a/src/9p_io.zig b/src/9p_io.zig
index 943561eb..d0db1c86 100644
--- a/src/9p_io.zig
+++ b/src/9p_io.zig
@@ -138,7 +138,7 @@ fn localIp(address: std.Io.net.IpAddress) bool {
return false;
}
-const Srv = ninep.Server(pardes.filesystem, ninep.max_fids);
+const Srv = ninep.Server(pardes.ctlfs, ninep.max_fids);
const Conn = struct {
fd: c_int = -1,
@@ -149,7 +149,7 @@ const Conn = struct {
in: [msize]u8 = undefined,
out: [2 * msize]u8 = undefined,
- fn step(c: *Conn, core: *pardes.Pardes, req: pardes.filesystem.Req) void {
+ fn step(c: *Conn, core: *pardes.Pardes, req: pardes.ctlfs.Req) void {
core.update(.{ .fs_req = req });
var answered = false;
while (core.nextEffect()) |effect| {
@@ -160,7 +160,7 @@ const Conn = struct {
} else core.perform(effect);
}
if (!answered) {
- const reply = pardes.filesystem.Reply.fail(req.tag, pardes.filesystem.E.IO);
+ const reply = pardes.ctlfs.Reply.fail(req.tag, pardes.ctlfs.E.IO);
c.srv.reply(&reply, "");
}
}
@@ -226,7 +226,7 @@ pub const Listener = struct {
c.srv = .init(.{
.in = &c.in,
.out = &c.out,
- .root = pardes.filesystem.namespace_root,
+ .root = pardes.ctlfs.root,
});
}
}
@@ -246,7 +246,7 @@ pub const Listener = struct {
c.quic = connection;
c.draining = false;
c.accepted_ms = nowMs();
- c.srv = .init(.{ .in = &c.in, .out = &c.out, .root = pardes.filesystem.namespace_root });
+ c.srv = .init(.{ .in = &c.in, .out = &c.out, .root = pardes.ctlfs.root });
};
}
}
@@ -748,17 +748,17 @@ test "Unix TCP and QUIC share one listener through reads writes reconnects and r
defer testing.allocator.free(before);
try testing.expectEqualStrings(w.expected, before);
try testing.expectError(error.FileTooLarge, Client.readLimit(testing.allocator, w.dial, w.body_path, w.body_path, w.expected.len - 1));
- const listing = try Client.readLimit(testing.allocator, w.dial, "/self/pane", "/self/pane", 128);
+ const listing = try Client.readLimit(testing.allocator, w.dial, "/pane", "/pane", 128);
defer testing.allocator.free(listing);
- const exact_listing = try Client.readLimit(testing.allocator, w.dial, "/self/pane", "/self/pane", listing.len);
+ const exact_listing = try Client.readLimit(testing.allocator, w.dial, "/pane", "/pane", listing.len);
defer testing.allocator.free(exact_listing);
try testing.expectEqualStrings(listing, exact_listing);
- try testing.expectError(error.FileTooLarge, Client.readLimit(testing.allocator, w.dial, "/self/pane", "/self/pane", listing.len - 1));
+ try testing.expectError(error.FileTooLarge, Client.readLimit(testing.allocator, w.dial, "/pane", "/pane", listing.len - 1));
try Client.write(testing.allocator, w.dial, w.body_path, w.replacement);
const after = try Client.read(testing.allocator, w.dial, w.body_path, w.body_path);
defer testing.allocator.free(after);
try testing.expectEqualStrings(w.replacement, after);
- const screen = try Client.read(testing.allocator, w.dial, "/self/screen", "/self/screen");
+ const screen = try Client.read(testing.allocator, w.dial, "/screen", "/screen");
defer testing.allocator.free(screen);
const parsed = try std.json.parseFromSlice(struct { cols: u16, rows: u16 }, testing.allocator, screen, .{ .ignore_unknown_fields = true });
defer parsed.deinit();
@@ -790,7 +790,7 @@ test "Unix TCP and QUIC share one listener through reads writes reconnects and r
var dial_buf: [64]u8 = undefined;
const network_dial = try std.fmt.bufPrint(&dial_buf, "{s}!{s}!{d}", .{ protocol, host, port });
var body_buf: [64]u8 = undefined;
- const body = try std.fmt.bufPrint(&body_buf, "/self/pane/{d}/body", .{pane.serial});
+ const body = try std.fmt.bufPrint(&body_buf, "/pane/{d}/body", .{pane.serial});
for ([_][]const u8{ network_dial, l.path(), network_dial }, 0..) |dial, attempt| {
var worker: Worker = .{ .dial = dial, .body_path = body, .expected = if (attempt == 0) "initial\n" else replacement, .replacement = replacement };
const thread = try std.Thread.spawn(.{}, Worker.run, .{&worker});
@@ -1245,15 +1245,14 @@ pub const Client = struct {
test "a path becomes walk elements, normalised the way a shell would" {
var out: [max_depth][]const u8 = undefined;
- try testing.expectEqual(@as(usize, 4), try elements("/self/pane/1/body", &out));
- try testing.expectEqualStrings("self", out[0]);
- try testing.expectEqualStrings("pane", out[1]);
- try testing.expectEqualStrings("1", out[2]);
- try testing.expectEqualStrings("body", out[3]);
+ try testing.expectEqual(@as(usize, 3), try elements("/pane/1/body", &out));
+ try testing.expectEqualStrings("pane", out[0]);
+ try testing.expectEqualStrings("1", out[1]);
+ try testing.expectEqualStrings("body", out[2]);
- try testing.expectEqual(@as(usize, 4), try elements("self/pane/1/body", &out));
- try testing.expectEqual(@as(usize, 4), try elements("//self//pane//1//body//", &out));
- try testing.expectEqual(@as(usize, 2), try elements("/self/index", &out));
+ try testing.expectEqual(@as(usize, 3), try elements("pane/1/body", &out));
+ try testing.expectEqual(@as(usize, 3), try elements("//pane//1//body//", &out));
+ try testing.expectEqual(@as(usize, 1), try elements("/index", &out));
try testing.expectEqual(@as(usize, 0), try elements("/", &out));
@@ -1284,12 +1283,12 @@ pub const Client = struct {
test "a dial with nothing listening is one error and not a wait" {
if (comptime !supported) return error.SkipZigTest;
var names: [max_depth][]const u8 = undefined;
- const n = try elements("/self/pane/1/body", &names);
+ const n = try elements("/pane/1/body", &names);
var remote: RemoteError = .{};
const before = nowMs();
try testing.expectError(
Error.Dial,
- fetchBytes(testing.allocator, .{ .unix = "/tmp/pardes-9p-no-such-socket.sock" }, names[0..n], &remote, null, "/self/pane/1/body", limits.max_file_bytes),
+ fetchBytes(testing.allocator, .{ .unix = "/tmp/pardes-9p-no-such-socket.sock" }, names[0..n], &remote, null, "/pane/1/body", limits.max_file_bytes),
);
try testing.expect(nowMs() - before < budget_ms);
}