repos / zmx

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

commit
25acaf8
parent
726a8e3
author
Eric Bower
date
2025-10-10 22:15:14 -0400 EDT
fix: more cleanup
4 files changed,  +41, -14
M src/attach.zig
+20, -11
 1@@ -45,21 +45,34 @@ pub fn main() !void {
 2     var loop = try xev.Loop.init(.{ .thread_pool = &thread_pool });
 3     defer loop.deinit();
 4 
 5-    // Save original terminal settings and set raw mode
 6+    var unix_addr = try std.net.Address.initUnix(socket_path);
 7+    // AF.UNIX: Unix domain socket for local IPC with daemon process
 8+    // SOCK.STREAM: Reliable, connection-oriented communication for protocol messages
 9+    // SOCK.NONBLOCK: Prevents blocking to work with libxev's async event loop
10+    const socket_fd = try posix.socket(posix.AF.UNIX, posix.SOCK.STREAM | posix.SOCK.NONBLOCK, 0);
11+    // Save original terminal settings first (before connecting)
12     var orig_termios: c.termios = undefined;
13     _ = c.tcgetattr(posix.STDIN_FILENO, &orig_termios);
14+
15+    posix.connect(socket_fd, &unix_addr.any, unix_addr.getOsSockLen()) catch |err| {
16+        if (err == error.ConnectionRefused) {
17+            std.debug.print("Error: Unable to connect to zmx daemon at {s}\nPlease start the daemon first with: zmx daemon\n", .{socket_path});
18+            std.process.exit(1);
19+        }
20+        return err;
21+    };
22+
23+    _ = posix.write(posix.STDERR_FILENO, "Attaching to session: ") catch {};
24+    _ = posix.write(posix.STDERR_FILENO, session_name) catch {};
25+    _ = posix.write(posix.STDERR_FILENO, "\n") catch {};
26+
27+    // Set raw mode after successful connection
28     defer _ = c.tcsetattr(posix.STDIN_FILENO, c.TCSANOW, &orig_termios);
29 
30     var raw_termios = orig_termios;
31     c.cfmakeraw(&raw_termios);
32     _ = c.tcsetattr(posix.STDIN_FILENO, c.TCSANOW, &raw_termios);
33 
34-    var unix_addr = try std.net.Address.initUnix(socket_path);
35-    // AF.UNIX: Unix domain socket for local IPC with daemon process
36-    // SOCK.STREAM: Reliable, connection-oriented communication for protocol messages
37-    // SOCK.NONBLOCK: Prevents blocking to work with libxev's async event loop
38-    const socket_fd = try posix.socket(posix.AF.UNIX, posix.SOCK.STREAM | posix.SOCK.NONBLOCK, 0);
39-    try posix.connect(socket_fd, &unix_addr.any, unix_addr.getOsSockLen());
40     const request = try std.fmt.allocPrint(
41         allocator,
42         "{{\"type\":\"attach_session_request\",\"payload\":{{\"session_name\":\"{s}\"}}}}\n",
43@@ -67,10 +80,6 @@ pub fn main() !void {
44     );
45     defer allocator.free(request);
46 
47-    _ = posix.write(posix.STDERR_FILENO, "Attaching to session: ") catch {};
48-    _ = posix.write(posix.STDERR_FILENO, session_name) catch {};
49-    _ = posix.write(posix.STDERR_FILENO, "\n") catch {};
50-
51     const ctx = try allocator.create(Context);
52     ctx.* = .{
53         .stream = xev.Stream.initFd(socket_fd),
M src/detach.zig
+7, -1
 1@@ -58,7 +58,13 @@ pub fn main() !void {
 2     const socket_fd = try posix.socket(posix.AF.UNIX, posix.SOCK.STREAM, 0);
 3     defer posix.close(socket_fd);
 4 
 5-    try posix.connect(socket_fd, &unix_addr.any, unix_addr.getOsSockLen());
 6+    posix.connect(socket_fd, &unix_addr.any, unix_addr.getOsSockLen()) catch |err| {
 7+        if (err == error.ConnectionRefused) {
 8+            std.debug.print("Error: Unable to connect to zmx daemon at {s}\nPlease start the daemon first with: zmx daemon\n", .{socket_path});
 9+            std.process.exit(1);
10+        }
11+        return err;
12+    };
13 
14     const request = if (client_fd) |fd|
15         try std.fmt.allocPrint(
M src/kill.zig
+7, -1
 1@@ -22,7 +22,13 @@ pub fn main() !void {
 2     const socket_fd = try posix.socket(posix.AF.UNIX, posix.SOCK.STREAM, 0);
 3     defer posix.close(socket_fd);
 4 
 5-    try posix.connect(socket_fd, &unix_addr.any, unix_addr.getOsSockLen());
 6+    posix.connect(socket_fd, &unix_addr.any, unix_addr.getOsSockLen()) catch |err| {
 7+        if (err == error.ConnectionRefused) {
 8+            std.debug.print("Error: Unable to connect to zmx daemon at {s}\nPlease start the daemon first with: zmx daemon\n", .{socket_path});
 9+            std.process.exit(1);
10+        }
11+        return err;
12+    };
13 
14     const request = try std.fmt.allocPrint(
15         allocator,
M src/list.zig
+7, -1
 1@@ -12,7 +12,13 @@ pub fn main() !void {
 2     const socket_fd = try posix.socket(posix.AF.UNIX, posix.SOCK.STREAM, 0);
 3     defer posix.close(socket_fd);
 4 
 5-    try posix.connect(socket_fd, &unix_addr.any, unix_addr.getOsSockLen());
 6+    posix.connect(socket_fd, &unix_addr.any, unix_addr.getOsSockLen()) catch |err| {
 7+        if (err == error.ConnectionRefused) {
 8+            std.debug.print("Error: Unable to connect to zmx daemon at {s}\nPlease start the daemon first with: zmx daemon\n", .{socket_path});
 9+            std.process.exit(1);
10+        }
11+        return err;
12+    };
13 
14     const request = "{\"type\":\"list_sessions_request\",\"payload\":{}}\n";
15     _ = try posix.write(socket_fd, request);