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