Discussion:
[ast-developers] signal traps and function scope? (was:Re: [ast-users] Inheriting signals from ksh functions.)
Cedric Blancher
2013-10-21 09:04:57 UTC
Permalink
How do you force a function to both inherit signals and accept local
variables?
$ ksh -c 'function f { typeset x=${.sh.fun}; trap "print -r caught in \$x" USR1; g; print -r "returning with $x"; }; function g { typeset x=${.sh.fun}; sleep 5; }; f & sleep 1; kill -s USR1 $!'
returning with f
$ ksh -c 'function f { typeset x=${.sh.fun}; trap "print -r caught in \$x" USR1; . g; print -r "returning with $x"; }; function g { typeset x=${.sh.fun}; sleep 5; }; f & sleep 1; kill -s USR1 $!'
caught in f
returning with f
caught in g
returning with f
I'm aware you can reset the trap within each function called from f, but that
isn't the same logic (if called from a different function that doesn't set the
trap) and probably implies a race condition until the function sets its own
handler.
David may know it better, but aren't signal traps per function with
scope (function foo1{}) and if you call another function with scope
which does not have a trap set the incoming signals are queued up and
*saved* until you return to the function with scope which has the trap
set?

That *was* my impression, but trying to use it showed that signal
traps are even executed in another function and scope:

cat test9.sh
function foo1
{
integer -r scope=2
print "> foo1"

trap 'printf "scope=%d: " scope ; print -C .sh.sig' RTMIN
print "> calling foo2"
foo2
print "> foo1 done"
}

function foo2
{
integer -r scope=3
float saved=SECONDS
integer pi=$$

{
sleep 2
for (( i=0 ; i < 3 ; i++ )) ; do
kill -Q $i -s RTMIN $pi
sleep 1
done
} &

while (( (SECONDS - saved) < 5. )) ; do
true
done

print '> waiting for child process'
wait
print '> child process finished'

print "> foo2 done"
}

set -o nounset
integer -r scope=1
foo1
~/bin/ksh test9.sh
foo1
calling foo2
scope=3: (typeset -r -l -i 16 addr=16#3e800000e1e;typeset -r -l -i
band=0;typeset -r code=SI_QUEUE;typeset -r -i errno=0;typeset -r
name=RTMIN;typeset -r -i pid=3614;typeset -r -i signo=34;typeset -r -i
status=0;typeset -r -i uid=1000;value=(typeset -r -i q=0;typeset -r -l
-u -i Q=0))
scope=3: (typeset -r -l -i 16 addr=16#3e800000e1e;typeset -r -l -i
band=0;typeset -r code=SI_QUEUE;typeset -r -i errno=0;typeset -r
name=RTMIN;typeset -r -i pid=3614;typeset -r -i signo=34;typeset -r -i
status=1;typeset -r -i uid=1000;value=(typeset -r -i q=1;typeset -r -l
-u -i Q=1))
scope=3: (typeset -r -l -i 16 addr=16#3e800000e1e;typeset -r -l -i
band=0;typeset -r code=SI_QUEUE;typeset -r -i errno=0;typeset -r
name=RTMIN;typeset -r -i pid=3614;typeset -r -i signo=34;typeset -r -i
status=2;typeset -r -i uid=1000;value=(typeset -r -i q=2;typeset -r -l
-u -i Q=2))
waiting for child process
child process finished
foo2 done
foo1 done
Why are the traps declared in foo1 executed in the function scope foo2
(as indicated by "scope=3" and the fact that the print -C output in
the trap comes long before "foo2 done") ?

Ced
--
Cedric Blancher <cedric.blancher at gmail.com>
Institute Pasteur
Loading...