- commit
- e17899d
- parent
- 377c062
- author
- Eric Bower
- date
- 2026-01-21 10:06:30 -0500 EST
fix: properly handle killing shells and children Shell's typically ignore SIGTERM unless there's a trap installed, but they will respond to SIGHUP. This works fine for shells but when a user runs `zig attach editor nvim` or any other non-shell command they might not respond to SIGHUP the way we want. So we have implemented a multi-signal approach: - SIGHUP - Wait 500ms - SIGKILL Reference: https://github.com/shell-pool/shpool/blob/1b3b27f059f0008c0509b5170d84b86c752b1da3/libshpool/src/daemon/shell.rs#L79-L94 Reference: https://github.com/neurosnap/zmx/pull/47
1 files changed,
+10,
-4
+10,
-4
1@@ -242,11 +242,18 @@ const Daemon = struct {
2
3 pub fn handleKill(self: *Daemon) void {
4 std.log.info("kill received session={s}", .{self.session_name});
5+ self.shutdown();
6+ // gracefully shutdown shell processes, shells tend to ignore SIGTERM so we send SIGHUP instead
7+ // https://www.gnu.org/software/bash/manual/html_node/Signals.html
8 // negative pid means kill process and children
9- posix.kill(-self.pid, posix.SIG.TERM) catch |err| {
10- std.log.warn("failed to send SIGTERM to pty child err={s}", .{@errorName(err)});
11+ std.log.info("sending SIGHUP session={s} pid={d}", .{ self.session_name, self.pid });
12+ posix.kill(-self.pid, posix.SIG.HUP) catch |err| {
13+ std.log.warn("failed to send SIGHUP to pty child err={s}", .{@errorName(err)});
14+ };
15+ std.Thread.sleep(500 * std.time.ns_per_ms);
16+ posix.kill(-self.pid, posix.SIG.KILL) catch |err| {
17+ std.log.warn("failed to send SIGKILL to pty child err={s}", .{@errorName(err)});
18 };
19- self.shutdown();
20 }
21
22 pub fn handleInfo(self: *Daemon, client: *Client) !void {
23@@ -1152,7 +1159,6 @@ fn daemonLoop(daemon: *Daemon, server_sock_fd: i32, pty_fd: i32) !void {
24 break :clients_loop;
25 },
26 .Kill => {
27- daemon.handleKill();
28 break :daemon_loop;
29 },
30 .Info => try daemon.handleInfo(client),