in reply to Re^3: Waiting for an External Program to Finish Executing
in thread Waiting for an External Program to Finish Executing

if doesn't just check for fork returning undef; it also checks for returning 0, which is what fork does in the child. From the manual:
(fork) returns ... 0 to the child process,

So this code is creating three processes:

When the grandchild finishes, its parent is already gone, so it's been reparented to init, which notices its death and waits for it, avoiding a zombie.

The OP's problem is that he's waiting for the child but running the long-running process in the grandchild. The fix is to eliminate the second fork, and just do the work in the child; the purpose of a second fork is to do something in the background without having to wait for it, which is what the OP is trying to avoid.

Here's a small example:

warn "PID $$ (parent) forking\n"; unless ($pid = fork) { warn " PID $$ (child) forking again\n"; unless (fork) { warn " PID $$ (grandchild) exec'ing\n"; exec "sleep 5"; die "Couldn't run getSite.pl"; exit 0; } warn " PID $$ (child) exiting\n"; exit 0; } warn "PID $$ (parent) executing waitpid\n"; waitpid($pid,0); warn "PID $$ (parent) done.\n";
outputs:
PID 6083 (parent) forking
  PID 6084 (child) forking again
    PID 6085 (grandchild) exec'ing
  PID 6084 (child) exiting
PID 6083 (parent) executing waitpid
PID 6083 (parent) done.

Here's a version which does what I believe the OP wants.

warn "PID $$ (parent) forking\n"; unless ($pid = fork) { warn " PID $$ (child) exec'ing\n"; exec "sleep 5"; die "Couldn't run getSite.pl"; } warn "PID $$ (parent) executing waitpid\n"; waitpid($pid,0); warn "PID $$ (parent) done.\n";

But, this is completely equivalent to system, so why not just use that?

Replies are listed 'Best First'.
Re^5: Waiting for an External Program to Finish Executing
by Moron (Curate) on Nov 15, 2005 at 10:00 UTC
    Every fork in the code is preceded by unless. unless (fork evaluating to undef()) is the only way any of the six branches can be followed and the only other possibility (pid=0) can't happen - it appears from your response you have projected your own ideas of intent and have lost the actual flow in that respect.

    -M

    Free your mind

      Why do you think that $pid == 0 "can't happen", when it's plainly documented that fork returns 0 in the child every single time it is executed? Have you actually called fork and observed its return values in parent and child to verify your assertion? If you don't think it returns 0 in the child, what do you think it returns, and how do you think the two processes know which is which?

      How do you think my sample code "(loses) the actual flow" when it's copied and pasted from the OP's, with minimal changes to have it output its flow?