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

Re: Commands run from functions don't exit cleanly on terminal close (SIGHUP)?

On Oct 27,  9:33pm, Alan Pinstein wrote:
} Oh, duh yes I was HUP'ing the php process. Well of course that's what
} would happen...

You didn't answer the question about which zsh version is involved.

} In any case I think that's kind of a digression; the simple truth is
} still that when the shell gets the SIGHUP from the Terminal program,
} it isn't propagating that to its children *if* the children are
} started in a function.

I think you're missing the point I've been trying to make.  Regardless
of whether the child is started from a function or not, closing the
terminal sends a HUP signal only to the foreground job.  This is what
is supposed to happen:

When zsh starts a job in the foreground, it makes that job the process
group leader for the terminal.  After that, until zsh itself exits, the
signals are all generated by the OS / terminal driver.

If you are at the ZLE prompt, then zsh is the foreground job.  It gets
the signal and/or EOF from the terminal, and (assuming NO_HUP is not
set) it explicitly sends HUP to all background children.

If you are not at the ZLE prompt -- e.g., your PHP program is running --
then the terminal wil HUP the PHP program, but will not HUP zsh.  *After*
that, it's possible that the behavior is different depending on whether
a function is involved, but it should be the case that only the "process
group leader" of the foreground process gets HUP'd.  This is an operating
system thing, not a zsh thing.

If the foreground job exits, then zsh will wake up and at some point
attempt to read from the terminal.  At that point it will get EOF, and
therefore (once again depending on NO_HUP) send HUP to all of its
background children.  In the case of your willnotdie function, the main
zsh loop is not re-entered until the function finishes, so zsh won't
see an EOF right away.

Now, I say that's what's supposed to happen, because there do seem to
be some cases on MacOS where it doesn't work that way.  In particular
with the stock 4.3.11 I see everything exit with no output from traps
ever written to the file; but with 5.0 compiled under macports, I get
output from the HUP trap.

} So I just re-did the test with a custom PHP script that logs signals
} (except for KILL and STOP, it can't).
} [...]

I can't test this because on my Mountain Lion iMac I get:

Fatal error: Call to undefined function pcntl_signal() in /private/tmp/trap.php
on line 5

which is very strange because php -v says

PHP 5.3.15 with Suhosin-Patch (cli) (built: Aug 24 2012 17:45:44)

} When run directly (php trap.php) and closing the terminal window, cat
} sig yields:
} > Sat Oct 27 21:20:41 EDT 2012
} So it looks like zsh sends KILL or STOP to all processes when ZSH
} itself gets the HUP from the Terminal?

No, zsh won't do that.  It never sends KILL or STOP.  Note, though, that
this is similar to the behavior of "willnotdie" that I observed on MacOS
with the stock 4.3.11.  Repeat my version question.

} And when run in a zsh function:
} > function p() { php trap.php }
} cat sig yields:
} Sat Oct 27 21:20:03 EDT 2012
} Sat Oct 27 21:20:14 EDT 2012

Note here that PHP still did not log a HUP signal, so it appears that
there is not a HUP being sent.
} *and* the PPID of the php process is 1 after the window closes...

Which means that zsh has already exited -- so either something external
is killing it (repeat my question about whether you're running ssh in a
terminal, or running a terminal in ssh), or the wait()-family system
call that zsh makes [to go dormant while PHP is in the foreground] has
returned so zsh was fooled into believing PHP had also exited.

Neither of these *ought* to happen.

Barton E. Schaefer

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