diff --git a/src/os/TempDir.zig b/src/os/TempDir.zig index 7c1354bae..7d3a34c84 100644 --- a/src/os/TempDir.zig +++ b/src/os/TempDir.zig @@ -31,7 +31,8 @@ pub fn init() !TempDir { const dir = dir: { const cwd = std.fs.cwd(); - const tmp_dir = internal_os.tmpDir() orelse break :dir cwd; + const tmp_dir = internal_os.allocTmpDir(std.heap.page_allocator) orelse break :dir cwd; + defer internal_os.freeTmpDir(std.heap.page_allocator, tmp_dir); break :dir try cwd.openDir(tmp_dir, .{}); }; diff --git a/src/os/file.zig b/src/os/file.zig index ee27addb0..e48524cdd 100644 --- a/src/os/file.zig +++ b/src/os/file.zig @@ -44,22 +44,26 @@ pub fn fixMaxFiles() void { } /// Return the recommended path for temporary files. -pub fn tmpDir() ?[]const u8 { +/// 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? const v = std.os.getenvW(std.unicode.utf8ToUtf16LeStringLiteral("TMP")) orelse return null; - // MAX_PATH is very likely sufficient, but it's theoretically possible for someone to - // configure their os to allow paths as big as std.os.windows.PATH_MAX_WIDE, which is MUCH - // larger. Even if they did that, though, it's very unlikey that their Temp dir will use - // such a long path. We can switch if we see any issues, though it seems fairly unlikely. - var buf = [_]u8{0} ** std.os.windows.MAX_PATH; - const len = std.unicode.utf16leToUtf8(buf[0..], v[0..v.len]) catch |e| { + return std.unicode.utf16leToUtf8Alloc(allocator, v) catch |e| { log.warn("failed to convert temp dir path from windows string: {}", .{e}); return null; }; - return buf[0..len]; } if (std.os.getenv("TMPDIR")) |v| return v; if (std.os.getenv("TMP")) |v| return v; return "/tmp"; } + +/// Free a path returned by tmpDir if it allocated memory. +/// This is a "no-op" for all platforms except windows. +pub fn freeTmpDir(allocator: std.mem.Allocator, dir: []const u8) void { + if (builtin.os.tag == .windows) { + allocator.free(dir); + } +} diff --git a/src/terminal/kitty/graphics_image.zig b/src/terminal/kitty/graphics_image.zig index 34dd2011f..fa20eaa10 100644 --- a/src/terminal/kitty/graphics_image.zig +++ b/src/terminal/kitty/graphics_image.zig @@ -192,7 +192,8 @@ pub const LoadingImage = struct { fn isPathInTempDir(path: []const u8) bool { if (std.mem.startsWith(u8, path, "/tmp")) return true; if (std.mem.startsWith(u8, path, "/dev/shm")) return true; - if (internal_os.tmpDir()) |dir| { + if (internal_os.allocTmpDir(std.heap.page_allocator)) |dir| { + defer internal_os.freeTmpDir(std.heap.page_allocator, dir); if (std.mem.startsWith(u8, path, dir)) return true; // The temporary dir is sometimes a symlink. On macOS for