mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-14 15:56:13 +03:00
core: if we change RLIMIT_NOFILE, reset it when executing commands
This commit is contained in:
@ -18,6 +18,7 @@ const Command = @This();
|
|||||||
|
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const builtin = @import("builtin");
|
const builtin = @import("builtin");
|
||||||
|
const global_state = &@import("global.zig").state;
|
||||||
const internal_os = @import("os/main.zig");
|
const internal_os = @import("os/main.zig");
|
||||||
const windows = internal_os.windows;
|
const windows = internal_os.windows;
|
||||||
const TempDir = internal_os.TempDir;
|
const TempDir = internal_os.TempDir;
|
||||||
@ -178,6 +179,10 @@ fn startPosix(self: *Command, arena: Allocator) !void {
|
|||||||
// If the user requested a pre exec callback, call it now.
|
// If the user requested a pre exec callback, call it now.
|
||||||
if (self.pre_exec) |f| f(self);
|
if (self.pre_exec) |f| f(self);
|
||||||
|
|
||||||
|
if (global_state.rlimits.nofile) |lim| {
|
||||||
|
internal_os.restoreMaxFiles(lim);
|
||||||
|
}
|
||||||
|
|
||||||
// Finally, replace our process.
|
// Finally, replace our process.
|
||||||
_ = posix.execveZ(pathZ, argsZ, envp) catch null;
|
_ = posix.execveZ(pathZ, argsZ, envp) catch null;
|
||||||
|
|
||||||
|
@ -27,6 +27,12 @@ pub const GlobalState = struct {
|
|||||||
alloc: std.mem.Allocator,
|
alloc: std.mem.Allocator,
|
||||||
action: ?cli.Action,
|
action: ?cli.Action,
|
||||||
logging: Logging,
|
logging: Logging,
|
||||||
|
/// If we change any resource limits for our own purposes, we save the
|
||||||
|
/// old limits so that they can be restored before we execute any child
|
||||||
|
/// processes.
|
||||||
|
rlimits: struct {
|
||||||
|
nofile: ?internal_os.rlimit = null,
|
||||||
|
} = .{},
|
||||||
|
|
||||||
/// The app resources directory, equivalent to zig-out/share when we build
|
/// The app resources directory, equivalent to zig-out/share when we build
|
||||||
/// from source. This is null if we can't detect it.
|
/// from source. This is null if we can't detect it.
|
||||||
@ -56,6 +62,7 @@ pub const GlobalState = struct {
|
|||||||
.alloc = undefined,
|
.alloc = undefined,
|
||||||
.action = null,
|
.action = null,
|
||||||
.logging = .{ .stderr = {} },
|
.logging = .{ .stderr = {} },
|
||||||
|
.rlimits = .{},
|
||||||
.resources_dir = null,
|
.resources_dir = null,
|
||||||
};
|
};
|
||||||
errdefer self.deinit();
|
errdefer self.deinit();
|
||||||
@ -124,7 +131,7 @@ pub const GlobalState = struct {
|
|||||||
std.log.info("libxev backend={}", .{xev.backend});
|
std.log.info("libxev backend={}", .{xev.backend});
|
||||||
|
|
||||||
// First things first, we fix our file descriptors
|
// First things first, we fix our file descriptors
|
||||||
internal_os.fixMaxFiles();
|
self.rlimits.nofile = internal_os.fixMaxFiles();
|
||||||
|
|
||||||
// Initialize our crash reporting.
|
// Initialize our crash reporting.
|
||||||
crash.init(self.alloc) catch |err| {
|
crash.init(self.alloc) catch |err| {
|
||||||
|
@ -4,23 +4,27 @@ const posix = std.posix;
|
|||||||
|
|
||||||
const log = std.log.scoped(.os);
|
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
|
/// 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.
|
/// need to do this because each window consumes at least a handful of fds.
|
||||||
/// This is extracted from the Zig compiler source code.
|
/// This is extracted from the Zig compiler source code.
|
||||||
pub fn fixMaxFiles() void {
|
pub fn fixMaxFiles() ?rlimit {
|
||||||
if (!@hasDecl(posix.system, "rlimit")) return;
|
if (!@hasDecl(posix.system, "rlimit")) return null;
|
||||||
|
|
||||||
var lim = posix.getrlimit(.NOFILE) catch {
|
const old = posix.getrlimit(.NOFILE) catch {
|
||||||
log.warn("failed to query file handle limit, may limit max windows", .{});
|
log.warn("failed to query file handle limit, may limit max windows", .{});
|
||||||
return; // Oh well; we tried.
|
return null; // Oh well; we tried.
|
||||||
};
|
};
|
||||||
|
|
||||||
// If we're already at the max, we're done.
|
// If we're already at the max, we're done.
|
||||||
if (lim.cur >= lim.max) {
|
if (old.cur >= old.max) {
|
||||||
log.debug("file handle limit already maximized value={}", .{lim.cur});
|
log.debug("file handle limit already maximized value={}", .{old.cur});
|
||||||
return;
|
return old;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var lim = old;
|
||||||
|
|
||||||
// Do a binary search for the limit.
|
// Do a binary search for the limit.
|
||||||
var min: posix.rlim_t = lim.cur;
|
var min: posix.rlim_t = lim.cur;
|
||||||
var max: posix.rlim_t = 1 << 20;
|
var max: posix.rlim_t = 1 << 20;
|
||||||
@ -41,6 +45,12 @@ pub fn fixMaxFiles() void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
log.debug("file handle limit raised value={}", .{lim.cur});
|
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.
|
/// Return the recommended path for temporary files.
|
||||||
|
@ -32,7 +32,9 @@ pub const getenv = env.getenv;
|
|||||||
pub const setenv = env.setenv;
|
pub const setenv = env.setenv;
|
||||||
pub const unsetenv = env.unsetenv;
|
pub const unsetenv = env.unsetenv;
|
||||||
pub const launchedFromDesktop = desktop.launchedFromDesktop;
|
pub const launchedFromDesktop = desktop.launchedFromDesktop;
|
||||||
|
pub const rlimit = file.rlimit;
|
||||||
pub const fixMaxFiles = file.fixMaxFiles;
|
pub const fixMaxFiles = file.fixMaxFiles;
|
||||||
|
pub const restoreMaxFiles = file.restoreMaxFiles;
|
||||||
pub const allocTmpDir = file.allocTmpDir;
|
pub const allocTmpDir = file.allocTmpDir;
|
||||||
pub const freeTmpDir = file.freeTmpDir;
|
pub const freeTmpDir = file.freeTmpDir;
|
||||||
pub const isFlatpak = flatpak.isFlatpak;
|
pub const isFlatpak = flatpak.isFlatpak;
|
||||||
|
Reference in New Issue
Block a user