100% CPU in a $EDITOR command due to the O_NONBLOCK set on STDIN_FILENO
Not sure if this is in your code or a library, but setting O_NONBLOCK on STDIN_FILENO and then forking out to an $EDITOR that assumes STDIN_FILENO is blocking can case 100% CPU usage in the $EDITOR. It may be prudent to default to turning off O_NONBLOCK across the fork/exec of the $EDITOR, and then to ensure that $EDITOR has not fiddled around with the blocking of the shared STDIN_FILENO afterwards.
(This was on OpenBSD 7.2 using ex(1) as the $EDITOR; I also have mailed a patch to the OpenBSD folks to turn off O_NONBLOCK in ex and vi.)
Thanks for reporting this.
I just tried this with neovim and it doesn't seem to have this issue.
The reason why we make stdin non-blocking is to work around a WSL bug: https://github.com/microsoft/WSL/issues/3507 (reported in tiny as #269)
We do it here: https://github.com/osa1/tiny/blob/847dfff59764d57b710922c66fdcef3c4c348448/crates/term_input/src/lib.rs#L244-L265
I discovered this issue in 2020, I wonder if the bug is fixed in recent versions of WSL. Maybe we can just remove this code. I'm on vacation now and don't have access to a Windows machine, so this will have to wait until next week.
Assuming the problem with WSL still exists, I agree that we may want to turn it off before running $EDITOR.
(This was on OpenBSD 7.2 using ex(1) as the $EDITOR; I also have mailed a patch to the OpenBSD folks to turn off O_NONBLOCK in ex and vi.)
Do they restore the mode on exit, or just update it on startup and then leave it with nonblock unset?
My patch (for my ex-vi) tries to restore the O_NONBLOCK at exit.
https://github.com/thrig/vi/commit/0aef961b32a7e5fd1a4861dda3883090255b97ed
... unless the process crashes, in which case O_NONBLOCK will not be restored.
It is almost certain that the OpenBSD folks will not accept the patch, though, as stdin is expected to be blocking; otherwise, one would need to add such a check to main() of practically every utility on unix, and likewise attempt to restore the flags, which again may not happen if the process crashes, or does an exec over to something else.
Can you set O_NONBLOCK only for WSL hosts? Or to have a compile flag to set the desired state?
Can you set O_NONBLOCK only for WSL hosts?
We can do that, but I'm not sure if there's a reliable way of checking this. I found this issue https://github.com/microsoft/WSL/issues/423 which shows a few ways of checking this, but I don't know if any of them are (1) reliable (2) work across versions we want to support (I don't even know how many versions exists and which ones we want to support).
Or to have a compile flag to set the desired state?
I don't want any more compile flags. We already have a few and it becomes difficult to test every combination of flags as the number increases. It also means more stuff to document, more release binaries etc.
We can transparently fix this issue, I just can't do it until next week. PRs are always welcome.