-
-
Notifications
You must be signed in to change notification settings - Fork 5.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
TUI: system(), systemlist(), :! in same process-group #8678
Comments
(This commit is for reference; the functional change will be reverted.) ref neovim#8217 ref neovim#8450 ref neovim#8678 In terminal-Vim, system() and :! run in Vim's process-group. But 8d90171 changed all of Nvim's process-spawn utilities to do setsid(), which conflicts with that expected terminal-Vim behavior. To "fix" that, this commit defines Process.detach as a TriState, then handles the kNone case such that system() and :! do not do setsid() in the spawned child. But this commit REGRESSES 8d90171 (neovim#8107), so for example the following code causes orphan processes: :echo system('sleep 30|sleep 30|sleep 30') Q: If we don't create a new session/process-group, how to avoid zombie descendants (e.g. process_wait() calls process_stop(), which only kills the root process)? A: Vim's approach in mch_call_shell_fork() is: 1. BLOCK_SIGNALS (ignores deadly) 2. fork() 3. unblock signals in the child 4. On CTRL-C, send SIGINT to the process-group id: kill(-pid, SIGINT) 5. Parent (vim) ignores the signal. Child (and descendants) do not. https://github.com/vim/vim/blob/e7499ddc33508d3d341e96f84a0e7b95b2d6927c/src/os_unix.c#L4834-L4841 https://github.com/vim/vim/blob/e7499ddc33508d3d341e96f84a0e7b95b2d6927c/src/os_unix.c#L5122-L5134 But we can't do that if we want to use the existing (libuv-based) form of process_spawn().
Currently both neovim and vim is doing wrong. To fix the problem once for all, use the following process:
Handle signalsHere is how we handle signals during step 7. As we already set the child as active process group, when user hit Ctrl-C, the SIGINT will be send to the active process group directly (aka, all process created by the command), this is the default pty behaviour. And it is the child's duty to clean up all his children. In most case, all children created will receive SIGINT from tty, and quit themself, if some processes refuse to exit by SIGINT, it is their choice, nothing related to neovim. Note
|
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
At least #8217 can be solved by changing I'll reopen this since I forgot about the workaround in the main description:
But really, the long-term solution is to use |
OK, I got your concept, and happy to progress this way. Currently uv_spawn is designed for detach process, which do use setsid but doesn't allocate pty. So I'm finding a way to replace it as you suggested,
|
Seems like this might be the cause of this: kovidgoyal/kitty#4869 Can anyone help me confirm? Any news on a fix? |
Would this fix the issue that the FAQ describes as
I use this a lot in Vim to launch TUIs (file manager, git, etc.) and would like to have this available in Neovim as well. |
No |
#8217 and #8450 describe some casualties of the change in #8107: since #8107, all processes spawned by Nvim are created in their own session (by calling
setsid()
in the child). Usingsetsid()
avoids serious bugs like #6530 (orphaned processes). It's a good thing to do, and is essentially what Vim'sjob_start()
does as well.However, the terminal version (at least) of Vim doesn't do that for
system()
,systemlist()
and:!
."Fixing" this as attempted in #8389 would regress #8107 for
system()
,systemlist()
, and:!
. For example, CTRL-C during this command would leave orphan processes:Vim's approach for
system()
,systemlist()
, and:!
is:fork()
vim
) ignores the signal. The child and its descendants do not, so sending the signal to the group kills everything exceptvim
itself.To do this in Nvim will (I think) require adding a case in
process_spawn()
to work without using libuv. This could be implemented like howsrc/nvim/os/pty_process_unix.c
implementsProcessType.kProcessTypePty
: addProcessType.kProcessTypeUnix
and special-case it.The work will be in implementing
src/nvim/os/unix_process.c
(again as mentioned,src/nvim/os/pty_process_unix.c
would be a good starting point).The text was updated successfully, but these errors were encountered: