f61b02b6
fix: the Darwin runtime-directory fallback is .macos by name
a73x 2026-09-04 10:16
Commit message
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" { |