aboutsummaryrefslogtreecommitdiff
path: root/vendor/libghostty-vt/src/os/file.zig
diff options
context:
space:
mode:
authorCan Celik <ogulcancelik@gmail.com>2026-04-04 19:22:04 +0300
committerCan Celik <ogulcancelik@gmail.com>2026-04-05 01:23:06 +0300
commit41dd733ca7123c9ac4bfc6c781697a660e95b052 (patch)
tree3fc91815ca139ef2e0b281bba0abda4ef15175f4 /vendor/libghostty-vt/src/os/file.zig
parent55c138263e190a1e79d4b997bfb9397306c0ec1f (diff)
feat: finish ghostty pane backend integration
Diffstat (limited to 'vendor/libghostty-vt/src/os/file.zig')
-rw-r--r--vendor/libghostty-vt/src/os/file.zig79
1 files changed, 79 insertions, 0 deletions
diff --git a/vendor/libghostty-vt/src/os/file.zig b/vendor/libghostty-vt/src/os/file.zig
new file mode 100644
index 00000000..240c936e
--- /dev/null
+++ b/vendor/libghostty-vt/src/os/file.zig
@@ -0,0 +1,79 @@
+const std = @import("std");
+const builtin = @import("builtin");
+const posix = std.posix;
+
+const log = std.log.scoped(.os);
+
+pub const rlimit = if (@hasDecl(posix.system, "rlimit")) posix.rlimit else struct {};
+
+/// 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() ?rlimit {
+ if (!@hasDecl(posix.system, "rlimit") or
+ posix.system.rlimit == void) return null;
+
+ const old = posix.getrlimit(.NOFILE) catch {
+ log.warn("failed to query file handle limit, may limit max windows", .{});
+ return null; // Oh well; we tried.
+ };
+
+ // If we're already at the max, we're done.
+ if (old.cur >= old.max) {
+ log.debug("file handle limit already maximized value={}", .{old.cur});
+ return old;
+ }
+
+ // Do a binary search for the limit.
+ var lim = old;
+ 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 old;
+}
+
+pub fn restoreMaxFiles(lim: rlimit) void {
+ if (!@hasDecl(posix.system, "rlimit")) return;
+ 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.
+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.process.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 (posix.getenv("TMPDIR")) |v| return v;
+ if (posix.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);
+ }
+}