Fix file descriptor leaks in async workers#856
Conversation
632bf77 to
d6ce109
Compare
Fixes marlonrichert#853 1. Correct a variable name typo in the clear function (_autocomplete__async_fd -> _autocomplete_async_fd). 2. Replace faulty terminal checks (-t) that prevented background pipes from closing. Use a safe redirection check ({ : <&$fd } 2>/dev/null) to verify pipe status before closing. 3. This resolves FD exhaustion (/dev/fd/-1) without redirecting global stderr, which previously silenced commands like git clone.
Replace -t (is-a-terminal) fd checks with actual read attempts to properly detect open file descriptors. The -t test only checks if an fd is a terminal, which is incorrect for pipes used by async workers, causing fd leaks. Also fixes variable name from _autocomplete__async_fd (double underscore) to _autocomplete_async_fd (single underscore) in the async:clear function. Ref: marlonrichert#856 Fixes: marlonrichert#853
|
I tested your branch and it does seem to fix the issue on my Debian machines, oddly enough this bug does not show up in my Ubuntu 24.04 environment. I'll switch to your branch for now until the fix will get merged, hopefully soon, since the bug is incredibly annoying. Thank you very much for your contribution! |
|
This fixed my issue as well (still had the issue with just the typo fix, the rest was needed too). |
|
@marlonrichert we've validated the patch proposed by @SaeGon-Heo fixes all leak issues. Can you review/merge this PR?
|
|
@marlonrichert |
|
Please treat this as a priority, this is killing me I had to turn off the plugin for the time being |
Poor Stuff |
same here |
@SaeGon-Heo This patch really works. Have you tried creating a brand new PR with clean commits/pushes so it can go through? |
|
@marlonrichert |
Note: The description for this PR was drafted with the help of Gemini 3.1 Pro.
Before submitting your Pull Request (PR), please check the following:
Fixes #<bug>orResolves #<issue>in its body (not subject, that is, the first line) for each issue it resolves (if any).The Problem
After extended use of the terminal, users experience recurring crashes with the following error messages, eventually completely breaking autocompletion:
This occurs because the plugin leaks file descriptors on every keystroke. Once the OS open-file limit is reached (commonly 256), Zsh fails to allocate new pipes for process substitution
<(...).Root Causes
Upon investigating
Functions/Init/.autocomplete__async, two bugs prevent FDs from closing:.autocomplete:async:clear: Theifcondition checks for_autocomplete__async_fd(double underscore), while the actual file descriptor is stored in_autocomplete_async_fd(single underscore). The cleanup block is bypassed entirely when exiting ZLE.[[ -t $fd ]]): In multiple functions, the code uses[[ -t $fd ]]before closing the descriptor viaexec {fd}<&-. The-tflag checks if an FD is connected to a terminal (TTY). Because the async workers use pipes, they are never connected to a terminal, so this evaluates tofalse100% of the time, leaking the FD.Proposed Changes
Functions/Init/.autocomplete__async:.autocomplete:async:clear.[[ -t $fd ]]checks in.autocomplete:async:clear,.autocomplete:async:wait:fd-widget, and.autocomplete:async:complete:fd-widget.{ : <&$fd } 2>/dev/null && exec {fd}<&-. This safely peeks to see if the file descriptor is open before closing it. Importantly, it avoids using a bareexec 2>/dev/null, which would unintentionally redirect the global shellstderrand break the output of background commands likegit clone.