(os/open.zig stderr drain => journal flood / self-DoS) + (ghostty OSC 8 parser doesn't handle hostname= param) #13267
Unanswered
mjbommar
asked this question in
Issue Triage
Replies: 1 comment
|
Confirming this on Void Linux (i3, GTK, Ghostty Environment
|
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Issue Description
I hit an issue today daily-driving tip that spiked CPU to 100% permanently until ghostty/service were killed. Claude and I debugged it and found that this to be two issues, one related to a long chain of tradeoffs/changes that are yet unresolved.
OSC 8 parser
When something like an SSH session renders a file URL, the OSC 8 standard says we should provide the FQDN as hostname= so that downstream users know how to resolve it.
src/terminal/osc/parsers/hyperlink.zigdoesn't do that, so when we try to use the result with something likexdg-openit fails.open.zig stderr drain
Here's the Claude summary and timeline:
[CLAUDE]
openThreadinsrc/os/open.zigdrains the child's stderr withreader.takeDelimiterExclusive('\n'). That std function returns the bytesup to the delimiter and tosses only those bytes — it never consumes the
\nitself (implemented aspeekDelimiterExclusive+toss(result.len),Zig 0.15.2
lib/std/Io/Reader.zig:815). So once a single newline isbuffered, every subsequent call has
peekDelimiterExclusivefind thedelimiter at position 0 and return an empty slice straight from the
buffer — no read syscall, no pipe interaction, no EOF — and the loop
never advances:
All three platforms share this code (
xdg-open/open/rundll32); the only precondition isthe child writing ≥1 newline-terminated line to stderr.
src/os/open.zighas cycled through adjacent failure modes; thisregression is the latest step. Not all of these co-occur — listed for
reviewer context, not as "all bugs are back at once."
695bc307b"do not wait for commands which do not terminate"openactions create zombie xdg-open processes"3d89fadc8):wait()in a detached thread;collectOutputcapped at 50 KiBerror.StreamTooLongkills the thread, leaking pipe read-endsopen.zigleaks pipe read-ends"bb375a2f7): stream stderr unbounded line-by-line, ignore stdoutUse
takeDelimiter, which advances past the delimiter and returnsnullat end-of-stream (also restoresexe.wait()reachability):[/CLAUDE]
I didn't check yet to see if there is a different safe idiom for consuming elsewhere, but you can see the propose fix there.
Expected Behavior
Drain properly
Actual Behavior
Infinite loop
Reproduction Steps
Try to open a file:// URL that fails
Ghostty Logs
Ghostty Version
OS Version Information
Ubuntu 26.04
(Linux only) Display Server
Wayland
(Linux only) Desktop Environment/Window Manager
GNOME 4.22.4
Minimal Ghostty Configuration
Additional Relevant Configuration
No response
I acknowledge that:
```) on separate lines.All reactions