[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
signal handling, killing background processes started under sub-shells
#!/usr/local/bin/es
#
# This buggy code (I think the code is buggy, I make no claims that es
# is buggy) was abstracted out of fairly complex es code which manages
# background processes. Normally, these background processes are
# killed after a timeout. However, the user may send an interrupt
# signal to the outermost es process. When the outermost es process
# is signaled, it should ensure that all children and below are killed
# before it exits completely.
#
# This code doesn't work as one might hope. Since the background
# process_that_should_not_exit_until_killed is created by an es
# sub-shell, the signal handler can't kill it using the obvious code
# shown below. Is there any way to ensure that an interrupt signal
# propagates to all background processes started in all sub-shells?
#
# I have found a number of workarounds which all involve forcing all
# background jobs to be started by the outermost es process.
#
# Note: this code does not appear to be buggy, if
# '|[2] process_output' is removed (thus making the 'sleep 10'
# and the background job direct children of the outermost
# es process).
#
# Note: even though I note the code is buggy, when run it still doesn't
# react as I might expect. E.g. As shown, 'killed children' is
# never printed when the outermost es process is sent the
# interrupt signal.
#
# 0.9-alpha1, sunos-4.1.4
#
# Any comments on this issue welcome, but I expect I have just hit a
# murky area of es and will resign myself to staying away from complex
# background job situations... :-)
fn process_that_should_not_exit_until_killed {sleep 10000}
fn process_output {cat >/dev/null}
local (signals = $signals sighup sigint) \
{
catch @ e {kill <=%apids >[2]/dev/null; echo killed children; throw $e} \
{
{
process_that_should_not_exit_until_killed &
# After timeout, kill background job (ensuring kill/wait is autonomous)
sleep 10
signals = $signals -sighup -sigint
kill $apid
wait
signals = $signals sighup sigint
} |[2] process_output
}
}