On Thu, Oct 14, 2021 at 04:28:14PM +0100, Bram Moolenaar <[email protected]> 
wrote:

> > > Since more than one person complained about this, and it still doesn't
> > > fully work with zsh, I'll revert 8.2.2919.  For zsh we need to find a
> > > different solution.
> > 
> > Thanks. Maybe blocking SIGHUP would fix the original problem with
> > background processes?
> 
> Hopefully someone can find out what the actualy problem is and find a
> solution that works and does not cause new problems.

Hmm, SIGHUP is already ignored in the gui.

My guess is that the original problem is that most
shells inherit gvim's ignoring of SIGHUP, but zsh
doesn't. So the command being executed doesn't ignore
SIGHUP either, and it dies when zsh terminates, rather
than when it's finished. But that is just a guess.

It's strange. The original bug report was for Arch Linux.
But it works fine on Debian Linux. It doesn't work on macOS.

I tried the following things on macOS:

  - Append "; wait" to the command
  - Prepend "setopt NO_HUP; " to the command
  - Prepend "trap '' HUP; " to the command
  - Prepend "setopt NO_HUP; trap '' HUP; " to the command
  - set shellcmdflag=-o\ nohup\ -c

The only thing that "fixed" it was appending "; wait"
to the command. Below is a patch that does that,
only when the gui is running and the shell is zsh and
there's an ampersand in the command (so "&&" will be a
false positive).

diff --git a/src/misc2.c b/src/misc2.c
index 8e01434ea..20c56edde 100644
--- a/src/misc2.c
+++ b/src/misc2.c
@@ -1766,6 +1766,29 @@ call_shell(char_u *cmd, int opt)
     proftime_T wait_time;
 #endif
 
+#ifdef FEAT_GUI
+    // Workaround a problem when executing a backgrounded command
+    // with zsh from the gui, by telling zsh to wait for it to complete.
+    // Otherwise, the command fails to function. Theory: Other shells
+    // inherit gvim's ignoring of SIGHUP, but maybe zsh is not ignoring it.
+
+    char_u  *modified_cmd = NULL;
+
+    if (cmd != NULL && gui.in_use && strstr((char *)gettail(p_sh), "zsh") != 
NULL && vim_strchr(cmd, (int)'&'))
+    {
+       const char  *suffix = "; wait";
+       size_t      suffix_len = strlen(suffix);
+       size_t      cmd_len = strlen((const char *)cmd);
+
+       modified_cmd = vim_strnsave(cmd, cmd_len + suffix_len);
+       if (modified_cmd != NULL)
+       {
+           memcpy(modified_cmd + cmd_len, suffix, suffix_len + 1); // "+ 1" is 
not necessary
+           cmd = modified_cmd;
+       }
+    }
+#endif
+
     if (p_verbose > 3)
     {
        verbose_enter();
@@ -1843,6 +1866,10 @@ call_shell(char_u *cmd, int opt)
     if (do_profiling == PROF_YES)
        prof_child_exit(&wait_time);
 # endif
+#endif
+#ifdef FEAT_GUI
+    if (modified_cmd != NULL)
+       vim_free(modified_cmd);
 #endif
 
     return retval;

But it's awful and hacky. It "fixes" the problem by
effectively disabling the ability to background a
process in zsh. And since it isn't a problem on Debian
Linux, it would make things slightly worse on some
systems, but only for commands that actually take a
long time to execute.

Unfortunately, dtruss on macOS isn't working well
enough for me to trace what's happening. Perhaps
someone with Arch Linux can use strace to investigate.

Until then, the most practical solution is to just:

  set shell=/bin/bash

That fixes it on macOS.

cheers,
raf

-- 
-- 
You received this message from the "vim_use" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_use" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_use/YWus3e2zGGT3aw%2Bk%40raf.org.

Reply via email to