repos / zmx

session persistence for terminal processes
git clone https://github.com/neurosnap/zmx.git

commit
cdbd72a
parent
077e51e
author
Eric Bower
date
2025-10-13 11:38:14 -0400 EDT
fix: move DA query handling to proper location
1 files changed,  +26, -25
M src/daemon.zig
+26, -25
 1@@ -613,25 +613,6 @@ fn handlePtyInput(client: *Client, text: []const u8) !void {
 2 
 3     std.debug.print("Writing {d} bytes to PTY fd={d}\n", .{ text.len, session.pty_master_fd });
 4 
 5-    // Intercept Device Attribute queries and respond directly
 6-    if (respondToDeviceAttributes(client, text)) |response| {
 7-        // Send response back to client instead of PTY
 8-        const header = protocol.FrameHeader{
 9-            .length = @intCast(response.len),
10-            .frame_type = @intFromEnum(protocol.FrameType.pty_binary),
11-        };
12-
13-        var frame_buf = std.ArrayList(u8).initCapacity(session.allocator, @sizeOf(protocol.FrameHeader) + response.len) catch return;
14-        defer frame_buf.deinit(session.allocator);
15-
16-        const header_bytes = std.mem.asBytes(&header);
17-        frame_buf.appendSlice(session.allocator, header_bytes) catch return;
18-        frame_buf.appendSlice(session.allocator, response) catch return;
19-
20-        _ = posix.write(client.fd, frame_buf.items) catch {};
21-        return; // Don't forward to PTY
22-    }
23-
24     // Write input to PTY master fd
25     const written = posix.write(session.pty_master_fd, text) catch |err| {
26         std.debug.print("Error writing to PTY: {s}\n", .{@errorName(err)});
27@@ -640,17 +621,23 @@ fn handlePtyInput(client: *Client, text: []const u8) !void {
28     _ = written;
29 }
30 
31-fn respondToDeviceAttributes(_: *Client, text: []const u8) ?[]const u8 {
32+fn respondToDeviceAttributes(session: *Session, data: []const u8) bool {
33     // Primary Device Attributes: CSI c or ESC [ c
34-    if (std.mem.eql(u8, text, "\x1b[c")) {
35+    if (std.mem.indexOf(u8, data, "\x1b[c")) |_| {
36         // VT220 with color and clipboard support
37-        return "\x1b[?62;22;52c";
38+        const response = "\x1b[?62;22;52c";
39+        _ = posix.write(session.pty_master_fd, response) catch return false;
40+        std.debug.print("Responded to Primary DA query\n", .{});
41+        return true;
42     }
43     // Secondary Device Attributes: CSI > c or ESC [ > c
44-    if (std.mem.eql(u8, text, "\x1b[>c")) {
45-        return "\x1b[>1;10;0c";
46+    if (std.mem.indexOf(u8, data, "\x1b[>c")) |_| {
47+        const response = "\x1b[>1;10;0c";
48+        _ = posix.write(session.pty_master_fd, response) catch return false;
49+        std.debug.print("Responded to Secondary DA query\n", .{});
50+        return true;
51     }
52-    return null;
53+    return false;
54 }
55 
56 fn handleWindowResize(client: *Client, rows: u16, cols: u16) !void {
57@@ -870,6 +857,20 @@ fn readPtyCallback(
58 
59         const valid_data = data[0..valid_len];
60 
61+        // Intercept Device Attribute queries from shell and respond
62+        if (respondToDeviceAttributes(session, valid_data)) {
63+            // Query was handled, don't forward to clients or store in buffer
64+            stream.read(
65+                loop,
66+                completion,
67+                .{ .slice = &session.pty_read_buffer },
68+                PtyReadContext,
69+                pty_ctx,
70+                readPtyCallback,
71+            );
72+            return .disarm;
73+        }
74+
75         // Store PTY output in buffer for session restore
76         session.buffer.appendSlice(session.allocator, valid_data) catch |err| {
77             std.debug.print("Buffer append error: {s}\n", .{@errorName(err)});