diff options
Diffstat (limited to 'src/builtins.zig')
| -rw-r--r-- | src/builtins.zig | 22 |
1 files changed, 21 insertions, 1 deletions
diff --git a/src/builtins.zig b/src/builtins.zig index cb588ba3..bc9bb075 100644 --- a/src/builtins.zig +++ b/src/builtins.zig @@ -742,9 +742,29 @@ pub const Attach = struct { if (comptime enabled) ask(c) else unreachable; } fn ask(c: Ctx) void { - const name = c.arg orelse ""; + const name = std.mem.trim(u8, c.arg orelse "", " \t\r\n"); if (name.len > pardes.attach_name_max) return c.p.reportError(c.id, comptime word(@This()), error.NameTooLong); + // A detached session has no terminal to move: bare, there is no + // "the one session there" but itself; a name is said for what it is. + if (c.p.opts.detached_session) { + if (name.len == 0) return c.p.reportFailure(c.id, "wrong #args in control message \"Attach\": a detached session names the session"); + // A session is its socket, `pardes-detached-<name>.sock` beside + // the 9P ones (detached/server.zig socketPath); not imported, as + // the core links no frontend's code. + const ninep_io = @import("9p_io.zig"); + var dir_buf: [ninep_io.sun_path_len:0]u8 = undefined; + var path_buf: [ninep_io.sun_path_len + 64:0]u8 = undefined; + const exists = if (ninep_io.socketDir(&dir_buf)) |dir| + (if (std.fmt.bufPrintSentinel(&path_buf, "{s}/pardes-detached-{s}.sock", .{ dir, name }, 0)) |path| ninep_io.statNoFollow(path) != null else |_| false) + else + false; + var said: [pardes.attach_name_max + 96]u8 = undefined; + return c.p.reportFailure(c.id, if (exists) + std.fmt.bufPrint(&said, "Attach: {s}: a detached session has no terminal to attach; Attach from a frontend", .{name}) catch "Attach: a detached session has no terminal to attach" + else + std.fmt.bufPrint(&said, "Attach: {s}: no such session", .{name}) catch "Attach: no such session"); + } c.p.emit(.{ .attach = .{ .pane = @intCast(c.id), .name = .from(name) } }); } }; |
