mirror of
https://github.com/ghostty-org/ghostty.git
synced 2026-09-14 18:01:58 +00:00
os/open: consume the newline when draining opener stderr
takeDelimiterExclusive never consumes the delimiter: it tosses only the exclusive length, so the '\n' stays buffered. Once the spawned opener writes a single line to stderr, every subsequent call returns an empty slice without advancing the stream, and openThread's loop spins forever - one pinned core per affected open(), logging empty "open stderr=" warnings at tens of thousands of messages per second for the lifetime of the process. The thread also never reaches exe.wait(), so the child is never reaped. Read inclusively instead (which does consume the delimiter) and trim the '\n' for logging. Repro: open a link whose handler writes to stderr, e.g. an OSC 8 link with an unknown scheme; watch a core disappear and the unified log flood with "os-open: open stderr=". See discussion #14100.
This commit is contained in:
@@ -86,7 +86,11 @@ fn openThread(io: std.Io, exe_: std.process.Child) void {
|
||||
var stream = stderr.readerStreaming(io, &buffer);
|
||||
const reader = &stream.interface;
|
||||
while (true) {
|
||||
const line = reader.takeDelimiterExclusive('\n') catch |outer| switch (outer) {
|
||||
// Read inclusively so the delimiter is consumed:
|
||||
// takeDelimiterExclusive leaves the '\n' buffered, so once the
|
||||
// child writes a line this loop would receive an empty slice
|
||||
// forever, pinning a core and spamming empty warnings.
|
||||
const line = reader.takeDelimiterInclusive('\n') catch |outer| switch (outer) {
|
||||
error.EndOfStream => break,
|
||||
error.ReadFailed => break,
|
||||
error.StreamTooLong => reader.take(buffer.len) catch |inner| switch (inner) {
|
||||
@@ -94,7 +98,7 @@ fn openThread(io: std.Io, exe_: std.process.Child) void {
|
||||
error.EndOfStream => break,
|
||||
},
|
||||
};
|
||||
log.warn("open stderr={s}", .{line});
|
||||
log.warn("open stderr={s}", .{std.mem.trimEnd(u8, line, "\n")});
|
||||
}
|
||||
}
|
||||
_ = exe.wait(io) catch {};
|
||||
|
||||
Reference in New Issue
Block a user