# SIGCHLD handler not working correctly

**URL:** <https://www.ruby-forum.com/t/sigchld-handler-not-working-correctly/123235>\
**Category:** Ruby\
**Created:** [December 15, 2007, 9:30am UTC](https://www.ruby-forum.com/t/sigchld-handler-not-working-correctly/123235 "2007-12-15T09:30:55Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![Asfand\_Yar\_Q](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/76d3ee/32.png) [@Asfand\_Yar\_Q](https://www.ruby-forum.com/u/Asfand_Yar_Q)\
**Post date:** [December 15, 2007, 9:30am UTC](https://www.ruby-forum.com/t/sigchld-handler-not-working-correctly/123235/1 "2007-12-15T09:30:55Z")

</div>

Hi,

Here’s some test code that demonstrates what I’m doing:

----------------------cut here----------------------

#!/usr/bin/ruby -w

trap\_quit = lambda { |sig|  
signame = Signal.list.find {|k, v| v == sig }[0]  
STDERR.puts(“Trapping signal #{signame}”)  
}

huphandler = inthandler = termhandler = chldhandler = nil  
huphandler = trap(“HUP”, &trap\_quit)  
inthandler = trap(“INT”, &trap\_quit)  
termhandler = trap(“TERM”, &trap\_quit)

cmd\_exitstatus = nil

chldhandler = trap(“CHLD”) {  
STDERR.puts(“Trapping signal CHLD”)  
begin  
# tmppid, status = Process.wait2(cmdpid)  
tmppid = Process.wait  
status = $?  
cmd\_exitstatus = status.exitstatus  
STDERR.puts("Process::Status =\> " + status.inspect)  
STDERR.puts("exitstatus =\> " + cmd\_exitstatus.inspect)  
if ! status.exited?  
raise “ARGH! The child has not exited yet!”  
end  
rescue Errno::ECHILD =\> e  
STDERR.puts(“Command failed - probably ok? #{e.inspect}”)  
# bah, ignore it, just means a command failed  
end  
}

cmdpid = fork {  
begin  
exec(“dd”, “if=/dev/zero”, “of=/tmp/zerofile1.asdfsdf”,  
“bs=1”, “count=333000000”)  
rescue Errno::ENOENT =\> e  
STDERR.puts e.message  
exit 127  
end  
}

while(cmd\_exitstatus.nil?)  
sleep 1  
STDOUT.puts “still going…”  
STDOUT.flush  
end

----------------------cut here----------------------

To see the problem, run the command, then press CTRL-C while it’s  
running. It will say “ARGH! The child has not exited yet!”

Inside the CHLD handler, exitstatus should be the valid exit status of  
the child process. However, it is nil. This is really really bad,  
because it seems to imply that the child signal, which is meant to be  
caught when a child exits, is being called while the child has NOT  
exited.

Anyone tell me what I’m doing wrong?

Thanks

–  
To reply, take of all ZIGs !!

Alternative email address: removed\_email\_address@domain.invalid

---

<div class="post-metadata">

**Author:** ![Asfand\_Yar\_Q](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/76d3ee/32.png) [@Asfand\_Yar\_Q](https://www.ruby-forum.com/u/Asfand_Yar_Q)\
**Post date:** [December 15, 2007, 2:18pm UTC](https://www.ruby-forum.com/t/sigchld-handler-not-working-correctly/123235/2 "2007-12-15T14:18:37Z")

</div>

Asfand Yar Q. wrote the following on 15.12.2007 09:30 :

> –
> 
> To see the problem, run the command, then press CTRL-C while it’s  
> running. It will say “ARGH! The child has not exited yet!”
> 
> Inside the CHLD handler, exitstatus should be the valid exit status of  
> the child process.

If I’m not mistaken, there’s none because the child didn’t call exit.

> However, it is nil. This is really really bad,  
> because it seems to imply that the child signal, which is meant to be  
> caught when a child exits, is being called while the child has NOT exited.

Looking at Process::Status#exited? documentation it seems it only  
returns true if the process actually exited on its own. Here dd dies  
because of a SIGINT (calling $?.signaled? returns true).

I’m not familiar with the signal handling details, so the following is  
no more than an educated guess.  
I believe that depending on the actual implementation of the signal  
handler you can get different reactions to a signal relative to exit  
status. Either:

- the program aborts _in the signal handler_ and don’t return an exit  
status,
- the signal handler is only used to modify internal structures and  
doesn’t abort the program right away. The normal course of the program  
only checks for the exit condition so you get a delayed “normal” exit  
controlled by a signal. In this case you get an exit status.

Lionel
