mirror of
https://github.com/ghostty-org/ghostty.git
synced 2026-08-24 16:11:43 +00:00
termio: release initial input resources (#13931)
Initial input files remained open and their fully read buffers remained allocated after queueWrite copied their contents. Close these files on both startup success and failure, free their contents after queueing, and borrow raw values already owned by the arena. **AI Usage:** This was spotted by GPT 5.6 Sol. I reworked the code a bit and understand it all.
This commit is contained in:
@@ -119,13 +119,15 @@ const ThreadEnterState = struct {
|
||||
) (Allocator.Error || error{InputNotFound})![]const Input {
|
||||
const alloc = self.arena.allocator();
|
||||
|
||||
var input = try alloc.alloc(
|
||||
Input,
|
||||
var inputs: std.ArrayList(Input) = try .initCapacity(
|
||||
alloc,
|
||||
self.input.list.items.len,
|
||||
);
|
||||
for (self.input.list.items, 0..) |item, i| {
|
||||
input[i] = switch (item) {
|
||||
.raw => |v| .{ .string = try alloc.dupe(u8, v) },
|
||||
errdefer for (inputs.items) |item| item.deinit();
|
||||
|
||||
for (self.input.list.items) |item| {
|
||||
inputs.appendAssumeCapacity(switch (item) {
|
||||
.raw => |v| .{ .string = v },
|
||||
.path => |path| file: {
|
||||
const f = std.Io.Dir.cwd().openFile(
|
||||
global.io(),
|
||||
@@ -141,15 +143,22 @@ const ThreadEnterState = struct {
|
||||
|
||||
break :file .{ .file = f };
|
||||
},
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
return input;
|
||||
return inputs.items;
|
||||
}
|
||||
|
||||
const Input = union(enum) {
|
||||
string: []const u8,
|
||||
file: std.Io.File,
|
||||
|
||||
fn deinit(self: Input) void {
|
||||
switch (self) {
|
||||
.string => {},
|
||||
.file => |f| f.close(global.io()),
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
@@ -346,6 +355,9 @@ pub fn threadEnter(
|
||||
try v.prepareInput()
|
||||
else
|
||||
null;
|
||||
defer if (inputs) |items| {
|
||||
for (items) |input| input.deinit();
|
||||
};
|
||||
|
||||
data.* = .{
|
||||
.alloc = self.alloc,
|
||||
@@ -366,20 +378,21 @@ pub fn threadEnter(
|
||||
log.warn("failed to queue input string err={}", .{err});
|
||||
return error.InputFailed;
|
||||
},
|
||||
.file => |f| self.queueWrite(
|
||||
data,
|
||||
compat_file.readToEndAlloc(
|
||||
.file => |f| {
|
||||
const contents = compat_file.readToEndAlloc(
|
||||
f,
|
||||
self.alloc,
|
||||
10 * 1024 * 1024, // 10 MiB max
|
||||
) catch |err| {
|
||||
log.warn("failed to read input file err={}", .{err});
|
||||
return error.InputFailed;
|
||||
},
|
||||
false,
|
||||
) catch |err| {
|
||||
log.warn("failed to queue input file err={}", .{err});
|
||||
return error.InputFailed;
|
||||
};
|
||||
defer self.alloc.free(contents);
|
||||
|
||||
self.queueWrite(data, contents, false) catch |err| {
|
||||
log.warn("failed to queue input file err={}", .{err});
|
||||
return error.InputFailed;
|
||||
};
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user