exec is a little different to how you describe, although the effect may be similar. The
exec command does a rather peculiar thing: it replaces the current program with a different one
in the same process. There is no return from a successful
exec, since the original code is lost. Some things do survive an
exec, the PID, open file handles, DEFAULT or IGNORE signal disposition, and ENVironment variables, to mention a few.
You imply you are doing some processing after the call to
system, yet looking at your code you appear to be doing an
exit(0). If it got to that point then the
exec did not work, so a
die (showing $!) might be better.
In the parent it is perfectly normal to call
waitpid, there is no need to place it in a CHLD signal handler. Using an argument of -1 (no need for WNOHANG) will wait on the next child to finish, and return its PID. For example (untested):
while (keys %fhlist) {
my $pid = waitpid(-1, 0);
delete $fhlist{$pid};
}
By the way, if you call
waitpid (or its sister
wait) for each of your children then you avoid zombies.