mirror of
https://github.com/ghostty-org/ghostty.git
synced 2026-05-19 19:41:27 +00:00
On Windows, the tmpDir function is currently using a buffer on the stack to convert the WTF16-encoded environment variable value "TMP" to utf8 and then returns it as a slice...but that stack buffer is no longer valid when the function returns. This was causing the "image load...temporary file" test to fail on Windows. I've updated the function to take an allocator but it only uses the allocator on Windows. No allocation is needed on other platforms because they return environment variables that are already utf8 (ascii) encoded, and the OS pre-allocates all environment variables in the process. To keep the conditional that determines when allocation is required, I added the `freeTmpDir` function.
70 lines
2.3 KiB
Zig
70 lines
2.3 KiB
Zig
const std = @import("std");
|
|
const builtin = @import("builtin");
|
|
|
|
const log = std.log.scoped(.os);
|
|
|
|
/// This maximizes the number of file descriptors we can have open. We
|
|
/// need to do this because each window consumes at least a handful of fds.
|
|
/// This is extracted from the Zig compiler source code.
|
|
pub fn fixMaxFiles() void {
|
|
if (!@hasDecl(std.os.system, "rlimit")) return;
|
|
const posix = std.os;
|
|
|
|
var lim = posix.getrlimit(.NOFILE) catch {
|
|
log.warn("failed to query file handle limit, may limit max windows", .{});
|
|
return; // Oh well; we tried.
|
|
};
|
|
|
|
// If we're already at the max, we're done.
|
|
if (lim.cur >= lim.max) {
|
|
log.debug("file handle limit already maximized value={}", .{lim.cur});
|
|
return;
|
|
}
|
|
|
|
// Do a binary search for the limit.
|
|
var min: posix.rlim_t = lim.cur;
|
|
var max: posix.rlim_t = 1 << 20;
|
|
// But if there's a defined upper bound, don't search, just set it.
|
|
if (lim.max != posix.RLIM.INFINITY) {
|
|
min = lim.max;
|
|
max = lim.max;
|
|
}
|
|
|
|
while (true) {
|
|
lim.cur = min + @divTrunc(max - min, 2); // on freebsd rlim_t is signed
|
|
if (posix.setrlimit(.NOFILE, lim)) |_| {
|
|
min = lim.cur;
|
|
} else |_| {
|
|
max = lim.cur;
|
|
}
|
|
if (min + 1 >= max) break;
|
|
}
|
|
|
|
log.debug("file handle limit raised value={}", .{lim.cur});
|
|
}
|
|
|
|
/// Return the recommended path for temporary files.
|
|
/// 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;
|
|
return std.unicode.utf16leToUtf8Alloc(allocator, v) catch |e| {
|
|
log.warn("failed to convert temp dir path from windows string: {}", .{e});
|
|
return null;
|
|
};
|
|
}
|
|
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);
|
|
}
|
|
}
|