Date:        Tue, 25 Apr 2017 15:21:24 +0200
    From:        Vincent Lefevre <vincent-o...@vinc17.net>
    Message-ID:  <20170425132124.ga7...@cventin.lip.ens-lyon.fr>

I see Jillles has said much the same thing while I was preparing
this, but ...

  | I wonder how the following script is supposed to behave.

I wonder more if it has any expected behaviour.

  | I would assume that the
  | trap would be executed for any child process that terminates, stops, or
  | continues. But this is not what I observe.

I suspect here that your observations are (partly) incorrect.

  | ------------------------------------------------------------------------
  | #!/bin/sh
  | 
  | n=${1:-30}
  | n=$((n+0))
  | 
  | c=0
  | trap 'c=$((c+1))' CHLD
  | 
  | for i in `seq $n`; do /bin/sleep 0.1 & done
  | 
  | while true
  | do
  |   echo $c
  |   /bin/sleep 0.1
  | done
  | ------------------------------------------------------------------------
  | 
  | I call this script with:
  | 
  |   <shell> <script_name>
  | 
  | Under Debian unstable:

  | * With ash, dash, mksh and yash, I get:

With the NetBSD sh (which is an ash derivative) that is what I see too.

  | So, I get +1 only for commands that are not executed in background
  | (asynchronously).

No, that does not fit with your observations.  If that were true,m the first
output value would be 0, as the exct is done before the first foreground
sleep.

What is happening here is that all the background processes are created
at about the same time, all run for very little time, and all will terminate
at essentially the same time.  There's nothing that requires signals to be
queued anywhere (though they may be).

What I ovserve is that all the background sleep processes have finished
before the shell gets to the while true loop, and exactly one SIGCHLD trap
gets executed by the shell (setting c to 1) and then after that, it
all goes as you observe.

Of course, all this is horribly racy, and other outputs might also occur,

  | * With bash and posh, I get:

  | i.e. no trap executions at all.

That is also not unreasonable - systems are permitted to rescind SIGCHLD
if a child process is waited upon - and it is entirely reasonable to block
SIGCHLD (and perhaps other signals) while in the wait handler, so if no
children die at a time that the shell happens to have SIGCHLD unblocked
(which might not be a very long interval) it is possile for no CHLD signals
will ever be delivered.

kre



Reply via email to