89de963b
fix: the spawn is an exec, not a fork — four comments still said fork
a73x 2026-08-29 02:18
Commit message
build.zig
| Old | New | ||
|---|---|---|---|
| @@ -924,9 +924,10 @@ pub fn build(b: *std.Build) void { | |||
| 924 | 924 | ||
| 925 | // ONE product binary. The four mains are modules under it, reached by | 925 | // ONE product binary. The four mains are modules under it, reached by |
| 926 | // the mode word rather than by four names on PATH — which is also what | 926 | // the mode word rather than by four names on PATH — which is also what |
| 927 | // lets the client's auto-start fork into the daemon instead of hunting | 927 | // lets the client's auto-start exec this same image with argv |
| 928 | // for a sibling. The fixtures below stay separate: they stand in for | 928 | // `mux d run …` (spawn.zig) instead of hunting PATH for a sibling. The |
| 929 | // users, not for the product. | 929 | // fixtures below stay separate: they stand in for users, not for the |
| 930 | // product. | ||
| 930 | const mux_exe = b.addExecutable(.{ .name = "mux", .root_module = mux_mod }); | 931 | const mux_exe = b.addExecutable(.{ .name = "mux", .root_module = mux_mod }); |
| 931 | // Zig 0.15's self-hosted x86_64 linker can't handle the .sframe | 932 | // Zig 0.15's self-hosted x86_64 linker can't handle the .sframe |
| 932 | // sections emitted by gcc >= 16 crt1.o on this system; LLD can. | 933 | // sections emitted by gcc >= 16 crt1.o on this system; LLD can. |
src/cli/main.zig
| Old | New | ||
|---|---|---|---|
| @@ -282,9 +282,9 @@ fn parseBindAddr(s: []const u8) !std.net.Address { | |||
| 282 | return std.net.Address.parseIp(hp.host, hp.port); | 282 | return std.net.Address.parseIp(hp.host, hp.port); |
| 283 | } | 283 | } |
| 284 | 284 | ||
| 285 | /// `mux d`. argv arrives from the dispatcher rather than from | 285 | /// `mux d`. argv arrives from the dispatcher, which has already eaten the |
| 286 | /// `argsAlloc`, because the local auto-start reaches this entry by fork | 286 | /// mode word, rather than from `argsAlloc`: one binary, four mains, and |
| 287 | /// instead of exec (spawn.zig) and a forked child has no argv of its own. | 287 | /// only the dispatcher knows where each mode's arguments start. |
| 288 | pub fn main(args: []const [:0]const u8) !u8 { | 288 | pub fn main(args: []const [:0]const u8) !u8 { |
| 289 | var gpa: std.heap.DebugAllocator(.{}) = .init; | 289 | var gpa: std.heap.DebugAllocator(.{}) = .init; |
| 290 | defer if (gpa.deinit() == .leak) | 290 | defer if (gpa.deinit() == .leak) |
test/coverage.sh
| Old | New | ||
|---|---|---|---|
| @@ -75,7 +75,8 @@ mkdir -p "$SHIM" "$RAW" | |||
| 75 | # would otherwise run its client traced in silence. The client mode is NOT | 75 | # would otherwise run its client traced in silence. The client mode is NOT |
| 76 | # in the default set, and that is a limitation rather than a preference: a | 76 | # in the default set, and that is a limitation rather than a preference: a |
| 77 | # traced client that auto-starts a daemon can never exit. The daemon is now | 77 | # traced client that auto-starts a daemon can never exit. The daemon is now |
| 78 | # a FORK of the client (spawn.zig) rather than an exec of a sibling, so it | 78 | # an exec of THIS image from a fork of the client (spawn.zig) rather than of |
| 79 | # a sibling on PATH, and ptrace follows an exec, so it | ||
| 79 | # is traced whenever the client is, stays traced after it reparents to | 80 | # is traced whenever the client is, stays traced after it reparents to |
| 80 | # init, and kcov waits for its last traced descendant — a process designed | 81 | # init, and kcov waits for its last traced descendant — a process designed |
| 81 | # never to end. The auto-start and `--via` legs wedge on this, and a | 82 | # never to end. The auto-start and `--via` legs wedge on this, and a |
test/e2e.sh
| Old | New | ||
|---|---|---|---|
| @@ -23,9 +23,9 @@ WSCLIENT="$6" | |||
| 23 | # The ssh recipes a handoff leg drives name `mux` and let the remote's PATH | 23 | # The ssh recipes a handoff leg drives name `mux` and let the remote's PATH |
| 24 | # find it, so the build's own bin directory goes in front of the shims that | 24 | # find it, so the build's own bin directory goes in front of the shims that |
| 25 | # stand in for a remote. The client's LOCAL auto-start no longer reads PATH | 25 | # stand in for a remote. The client's LOCAL auto-start no longer reads PATH |
| 26 | # at all — it forks into this binary's own daemon (spawn.zig) — so a leg | 26 | # at all — it execs this same binary with argv `mux d run …` (spawn.zig) — |
| 27 | # that forgets its `mux d run &` can no longer silently grade an installed | 27 | # so a leg that forgets its `mux d run &` can no longer silently grade an |
| 28 | # release, which it did against a v0.0.1-10 with no agent code in it. | 28 | # installed release, which it did against a v0.0.1-10 with no agent code. |
| 29 | PATH="$(cd "$(dirname "$MUX")" && pwd):$PATH" | 29 | PATH="$(cd "$(dirname "$MUX")" && pwd):$PATH" |
| 30 | export PATH | 30 | export PATH |
| 31 | 31 | ||