From 1ae27f95b43edeece2bdade3dbcecc9d455f0e5f Mon Sep 17 00:00:00 2001 From: Jon Parise Date: Thu, 23 Apr 2026 11:31:37 -0400 Subject: [PATCH] os: trim trailing path separators from tmpdir Because we generally read this value from an environment variable, we the resulting value can include a trailing slash (as on macOS). This results in less-friendly path operations for callers who are building paths based on this value. `std.fs.path.join()` handles trailing slashes just fine, but it's an allocating API. For callers who just want to format a path, they have to assume they need to include their own path separator. We can make this friendlier by always trimming trailing path separators from the environment variable values before returning the slice. This behavior matches "higher-level" languages' standard libraries (I checked Python, Node, Ruby, and Perl). Other "systems" languages (Go, Rust) just return the system value as-is, like we were doing before. --- src/os/file.zig | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/os/file.zig b/src/os/file.zig index 240c936e0..dc2d9f857 100644 --- a/src/os/file.zig +++ b/src/os/file.zig @@ -53,9 +53,12 @@ pub fn restoreMaxFiles(lim: rlimit) void { posix.setrlimit(.NOFILE, lim) catch {}; } -/// Return the recommended path for temporary files. -/// This may not actually allocate memory, use freeTmpDir to properly -/// free the memory when applicable. +/// Return the recommended path for temporary files. Any trailing +/// path separator is stripped so callers can safely join with their +/// own separator (e.g. `"{tmp}/{name}"`). +/// +/// This may not actually allocate memory; use `freeTmpDir` to +/// properly free the memory when applicable. pub fn allocTmpDir(allocator: std.mem.Allocator) ?[]const u8 { if (builtin.os.tag == .windows) { // TODO: what is a good fallback path on windows? @@ -65,9 +68,8 @@ pub fn allocTmpDir(allocator: std.mem.Allocator) ?[]const u8 { return null; }; } - if (posix.getenv("TMPDIR")) |v| return v; - if (posix.getenv("TMP")) |v| return v; - return "/tmp"; + const tmpdir = posix.getenv("TMPDIR") orelse posix.getenv("TMP") orelse return "/tmp"; + return std.mem.trimEnd(u8, tmpdir, &.{std.fs.path.sep}); } /// Free a path returned by tmpDir if it allocated memory.