Skip to content

Commit

Permalink
Move resource limits to a dedicated struct, restore before preexec
Browse files Browse the repository at this point in the history
  • Loading branch information
mitchellh committed Jan 2, 2025
1 parent 9ea0aa4 commit 8e47d02
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 14 deletions.
8 changes: 4 additions & 4 deletions src/Command.zig
Original file line number Diff line number Diff line change
Expand Up @@ -176,13 +176,13 @@ fn startPosix(self: *Command, arena: Allocator) !void {
// We don't log because that'll show up in the output.
};

// Restore any rlimits that were set by Ghostty. This might fail but
// any failures are ignored (its best effort).
global_state.rlimits.restore();

// If the user requested a pre exec callback, call it now.
if (self.pre_exec) |f| f(self);

if (global_state.rlimits.nofile) |lim| {
internal_os.restoreMaxFiles(lim);
}

// Finally, replace our process.
_ = posix.execveZ(pathZ, argsZ, envp) catch null;

Expand Down
29 changes: 21 additions & 8 deletions src/global.zig
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,7 @@ pub const GlobalState = struct {
alloc: std.mem.Allocator,
action: ?cli.Action,
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,
} = .{},
rlimits: ResourceLimits = .{},

/// The app resources directory, equivalent to zig-out/share when we build
/// from source. This is null if we can't detect it.
Expand Down Expand Up @@ -130,8 +125,8 @@ pub const GlobalState = struct {
std.log.info("renderer={}", .{renderer.Renderer});
std.log.info("libxev backend={}", .{xev.backend});

// First things first, we fix our file descriptors
self.rlimits.nofile = internal_os.fixMaxFiles();
// As early as possible, initialize our resource limits.
self.rlimits = ResourceLimits.init();

// Initialize our crash reporting.
crash.init(self.alloc) catch |err| {
Expand Down Expand Up @@ -181,3 +176,21 @@ pub const GlobalState = struct {
}
}
};

/// Maintains the Unix resource limits that we set for our process. This
/// can be used to restore the limits to their original values.
pub const ResourceLimits = struct {
nofile: ?internal_os.rlimit = null,

pub fn init() ResourceLimits {
return .{
// Maximize the number of file descriptors we can have open
// because we can consume a lot of them if we make many terminals.
.nofile = internal_os.fixMaxFiles(),
};
}

pub fn restore(self: *const ResourceLimits) void {
if (self.nofile) |lim| internal_os.restoreMaxFiles(lim);
}
};
3 changes: 1 addition & 2 deletions src/os/file.zig
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,8 @@ pub fn fixMaxFiles() ?rlimit {
return old;
}

var lim = 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.
Expand Down

0 comments on commit 8e47d02

Please sign in to comment.