a73x

f61b02b6

fix: the Darwin runtime-directory fallback is .macos by name

a73x   2026-09-04 10:16

Commit message
fix: the Darwin runtime-directory fallback is .macos by name

`runtimeDirFrom` handed /tmp/mux-UID to every tag that was not Linux, and
`runtimeDir` had no comptime refusal left after the OS branch replaced it.
A third arm would have inherited a Darwin directory chosen for a Darwin
reason: sun_path leaves no room for $TMPDIR or ~/Library/Caches, which is
an argument about macOS and about nothing else.

`runtimeDir` now names .linux and .macos and @compileErrors on anything
else, and the fallback switch answers null for a tag it does not know.
A test passes .freebsd and asserts the null, since that tag reaches the
function as an argument in the Linux gate.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SakwJEwD9dXBoRP5kWbemW

src/sockpath.zig
Old New
@@ -66,6 +66,16 @@ else
66 /// is sticky and world-writable, so the per-uid directory is what carries 66 /// is sticky and world-writable, so the per-uid directory is what carries
67 /// the privacy, as tmux's /tmp/tmux-UID does. 67 /// the privacy, as tmux's /tmp/tmux-UID does.
68 pub fn runtimeDir() ?[]const u8 { 68 pub fn runtimeDir() ?[]const u8 {
69 // The two OSes this builds for are named here rather than left as a
70 // linux-or-everything-else branch. `src/os/`'s roots already refuse a
71 // third tag at comptime, so a build for one cannot get this far today;
72 // this keeps the promise local, so that the day a third arm lands the
73 // compiler asks what its runtime directory is instead of silently
74 // handing it Darwin's /tmp fallback.
75 switch (builtin.os.tag) {
76 .linux, .macos => {},
77 else => @compileError("sockpath.runtimeDir: name this OS's runtime directory rule"),
78 }
69 const env = std.posix.getenv("XDG_RUNTIME_DIR"); 79 const env = std.posix.getenv("XDG_RUNTIME_DIR");
70 if (builtin.os.tag == .linux) return env; 80 if (builtin.os.tag == .linux) return env;
71 const uid = std.posix.geteuid(); 81 const uid = std.posix.geteuid();
@@ -89,8 +99,15 @@ var darwin_dir_buf: [32]u8 = undefined;
89 /// would ship green. 99 /// would ship green.
90 fn runtimeDirFrom(os: std.Target.Os.Tag, env: ?[]const u8, uid: std.posix.uid_t, buf: *[32]u8) ?[]const u8 { 100 fn runtimeDirFrom(os: std.Target.Os.Tag, env: ?[]const u8, uid: std.posix.uid_t, buf: *[32]u8) ?[]const u8 {
91 if (env) |e| return e; 101 if (env) |e| return e;
92 if (os == .linux) return null; 102 // `.macos` by name, not "not linux". The fallback is a Darwin rule with
93 return std.fmt.bufPrint(buf, "/tmp/mux-{d}", .{uid}) catch null; 103 // a Darwin reason (sun_path leaves no room for $TMPDIR or
104 // ~/Library/Caches), so a tag that is neither gets no directory rather
105 // than a borrowed one. `runtimeDir` refuses such a tag at comptime; this
106 // is the same answer for the callers that name the OS themselves.
107 return switch (os) {
108 .macos => std.fmt.bufPrint(buf, "/tmp/mux-{d}", .{uid}) catch null,
109 else => null,
110 };
94 } 111 }
95 112
96 /// True when PATH is a directory this uid owns with mode 0700 and no 113 /// True when PATH is a directory this uid owns with mode 0700 and no
@@ -404,6 +421,11 @@ test "runtimeDirFrom: the env var wins on every OS, and Darwin falls back to /tm
404 // the OS is an argument rather than a comptime branch: a typo in the 421 // the OS is an argument rather than a comptime branch: a typo in the
405 // format string is caught by CI rather than by the first Mac to run it. 422 // format string is caught by CI rather than by the first Mac to run it.
406 try std.testing.expectEqualStrings("/tmp/mux-501", runtimeDirFrom(.macos, null, 501, &buf).?); 423 try std.testing.expectEqualStrings("/tmp/mux-501", runtimeDirFrom(.macos, null, 501, &buf).?);
424
425 // A third OS gets NOTHING, rather than Darwin's directory because it is
426 // not Linux. `runtimeDir` refuses such a tag at comptime, so this is the
427 // answer for the callers that pass a tag rather than read `builtin`.
428 try std.testing.expect(runtimeDirFrom(.freebsd, null, 501, &buf) == null);
407 } 429 }
408 430
409 test "ensureOwnedDir: creates 0700, accepts its own creation, refuses a symlink and a group-readable dir" { 431 test "ensureOwnedDir: creates 0700, accepts its own creation, refuses a symlink and a group-readable dir" {