summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-09-30 21:14:06 -0300
committerGabriel Schneider <[email protected]>2026-10-01 00:12:17 -0300
commita2c719779c9ce0f676fb159135675df6275e77bf (patch)
treedd4752d91d50f73a4b1ed7ff031bfea00c6aac62 /src
parent27f8f6e0a5bb2751e1642db1e7e68b2cf72e50b0 (diff)
downloadpardes-a2c719779c9ce0f676fb159135675df6275e77bf.tar.gz
pardes-a2c719779c9ce0f676fb159135675df6275e77bf.zip
Forwarding pardes @pN for a pane the session has not is refused, "this session has no such pane", exit 1 and no pane made; one it has is looked at
@p999:1 was taken as a new file's name, so a pane named <cwd>/@p999 was made and the launch succeeded; an @pN the session did have was the same stray pane. A pane address is now checked against the session: one it has is a look at it, one it has not is refused with the reason and exit 1, as a refused name is. Co-Authored-By: Claude Opus 5.5 <[email protected]>
Diffstat (limited to 'src')
-rw-r--r--src/main.zig16
1 files changed, 16 insertions, 0 deletions
diff --git a/src/main.zig b/src/main.zig
index 6c5eaba1..3218fef1 100644
--- a/src/main.zig
+++ b/src/main.zig
@@ -106,6 +106,8 @@ fn forwardWords(err: anyerror, buf: []u8) []const u8 {
error.NotOneLine => "a file name is one line, and this one holds a newline",
error.NotAFileName => "names a directory, not a file",
error.NoWorkingDirectory => "this shell's working directory is gone",
+ error.NotAPaneAddress => "not a pane address: @p and a pane's number",
+ error.NoSuchPane => "this session has no such pane",
else => if (pardes.Messages.dialReason(err)) |why| why else words: {
var n: usize = 0;
for (@errorName(err), 0..) |c, i| {
@@ -450,6 +452,20 @@ fn nativeMain(init: std.process.Init) !void {
var home_buf: [4096]u8 = undefined;
const word = pardes.filesystem.expandHome(typed_word, &home_buf);
const target = @import("look.zig").parsePathLine(word);
+ // `@pN[:addr]` addresses a pane of this session: one it has is
+ // looked at, one it has not is refused, never a file of that name.
+ if (std.mem.startsWith(u8, target.path, pardes.config.pane_addr)) {
+ const digits = word[pardes.config.pane_addr.len .. std.mem.indexOfScalar(u8, word, ':') orelse word.len];
+ const serial = std.fmt.parseInt(u32, digits, 10) catch Refuse.with(init.io, word, error.NotAPaneAddress);
+ var name_buf: [64]u8 = undefined;
+ const name = try std.fmt.bufPrint(&name_buf, "/pane/{d}/name", .{serial});
+ const named = ninep_io.Client.read(arena, parent.dial, name, name) catch Refuse.with(init.io, word, error.NoSuchPane);
+ arena.free(named);
+ var command_buf: [4200]u8 = undefined;
+ const command = std.fmt.bufPrint(&command_buf, "{s}\n", .{word}) catch |err| Refuse.with(init.io, word, err);
+ ninep_io.Client.write(arena, parent.dial, look, command) catch |err| Refuse.with(init.io, word, err);
+ return;
+ }
var realbuf: [4096]u8 = undefined;
var newbuf: [4096]u8 = undefined;
const found_path: ?[]const u8 = if (pardes.filesystem.isVirtual(target.path)) target.path else if (pardes.filesystem.resolveOs(target.path, &realbuf)) |r| r.path else null;