Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: long-standing tty related issue: wrapped Emacs not suspended



On Thu, Sep 20, 2018 at 02:30:05PM +0200, Vincent Lefevre wrote:
> A long-standing tty related issue...
> 
> I often run Emacs in background:
> 
>   emacs &
> 
> This makes sense as it has its own X interface. But I sometimes do
> this when I forgot that I was in a SSH session with no X forwarding,
> and this makes the terminal unusable since Emacs is not suspended
> and both zsh and Emacs try to get terminal input.
> 
> Now I've noticed that when I run the Emacs binary directly, Emacs
> is suspended as expected. But when Emacs is wrapped in a function,
> it is not suspended. After "zsh -f":
> 
> zira% e() { emacs -nw "$@"; }
> zira% e &
> 
> I cannot quit Emacs or get the zsh prompt. I need to kill the
> terminal.
> 
> I've tested the same thing with other shells: dash behaves like
> zsh, and bash, ksh93 and mksh immediately terminate.
> 
> The same thing happens when using a sh script instead of a function.
> 
> Is this a bug? In any case, can this be solved?

So there is a bit of subtlety at work here cause your issues.

Note the difference between these two `pstree $$` outputs:

The broken case:
$ f() { emacs -nw "$@"; }; f &
zsh─┬─pstree
    ├─zsh───emacs───{emacs}

A working alternative:
$ f() { emacs -nw "$@" & }; f
zsh─┬─pstree
    ├─emacs───{emacs}

In the broken one, your terminal control commands like fg are being sent
to the parent zsh instance, which resumes the zsh subshell. I don't know
the specifics of how emacs' internals work, but usually editors tend to
suspend themselves when they can no longer read/write to or from the
foreground terminal, and Long story short, emacs is stuck suspended and
nested in a subshell, unable to receive your resume commands as the
subshell is intercepting them.

I don't actually know if you can resume emacs in that state, but anyway the
simpler workaround is to use something like `f() { emacs -nw "$@" & }; f`
where having the & inside the function itself avoids the extra subshell and
gives you expected behavior.

I don't know if I would really call this a bug, as pretty much all
common shells these have this same behavior or some other similar
way of handling like simply exiting when put in this odd situation.

I am unsure if this due to historical cruft with how terminals
are implemented these days, so maybe someone else can shed some light
on the reason this is the case.

-- 
Cheers,
Joey Pabalinas

Attachment: signature.asc
Description: PGP signature



Messages sorted by: Reverse Date, Date, Thread, Author