Commit 0a18bee
matt chow
·
2026-10-16 11:03:38 -0400 EDT
parent 35b8783
fix(daemon): don't drop a client's unread input on hangup A client that writes and exits (e.g. `zmx send`, `zmx run -d`) can be polled with IN and HUP together while part of its message is still in the socket. Each pass reads at most 4 KiB, so the HUP check in the same pass closed the client and the rest of the message was discarded: no log line, and the sender had already exited 0. Leave such a client for the next pass instead of closing it; the reads carry on until EOF, which closes it through the existing n == 0 path. ERR/NVAL still close at once.
2 files changed,
+7,
-0
+1,
-0
| ... | ... | @@ -25,6 +25,7 @@ Use spec: https://common-changelog.org/ | |
| 25 | 25 | - Prevent infinite loop in `mkdirAll` when directory path contains a dangling symlink | |
| 26 | 26 | - Prevent terminal and kitty keyboard queries from taking leadership control | |
| 27 | 27 | - Fixed missing terminal snapshot when attaching to a session originally started detached or via `zmx run` | |
| 28 | + | - Don't drop a client's unread input on hangup | |
| 28 | 29 | ||
| 29 | 30 | ## v0.8.1 - 2026-09-05 | |
| 30 | 31 |
+6,
-0
| ... | ... | @@ -536,6 +536,12 @@ fn daemonLoop(daemon: *Daemon, gpa: std.mem.Allocator, io: std.Io, server_sock_f | |
| 536 | 536 | } | |
| 537 | 537 | ||
| 538 | 538 | if (revents & (lib_posix.POLL.HUP | lib_posix.POLL.ERR | lib_posix.POLL.NVAL) != 0) { | |
| 539 | + | // A client that writes and exits (`zmx send`, `zmx run -d`) is | |
| 540 | + | // reported HUP with part of its message still unread: a pass | |
| 541 | + | // reads at most 4 KiB. Closing now drops the rest. Leave it to | |
| 542 | + | // the next pass, which reads on until EOF closes the client. | |
| 543 | + | if (revents & lib_posix.POLL.IN != 0 and | |
| 544 | + | revents & (lib_posix.POLL.ERR | lib_posix.POLL.NVAL) == 0) continue; | |
| 539 | 545 | const last = daemon.closeClient(gpa, client, i, false); | |
| 540 | 546 | if (last) break :daemon_loop; | |
| 541 | 547 | } |