http://qs1969.pair.com?node_id=136375

Marcello has asked for the wisdom of the Perl Monks concerning the following question:

Hi, I have the following code:
# create new directory here if (($pid = fork()) == 0) { # remove directory here } if (!defined($pid)) { # log fork() failure here # remove directory here }
As I see it, the newly created directory should always be removed. But sometimes the directory is mysteriously still there, without any fork() errors in my logfile.

BTW, I also write an entry in the logfile is the removal of the directory fails, this is also not the case, so it looks like it never reaches the code in the child process.

Can it be that although $pid is defined, the fork() fails? And how can I catch still situation in the above code?

Any input is highly appreciated

Replies are listed 'Best First'.
Re: mysterious fork() failure
by dws (Chancellor) on Jan 05, 2002 at 01:11 UTC
    # create new directory here if (($pid = fork()) == 0) { # remove directory here } if (!defined($pid)) { # log fork() failure here # remove directory here }
    You need to reverse your tests, and check for undef'ness of $pid first. For enlightenment as to why, ponder on   print undef == 0 ? "true!\n" : "false\n";
      So,
      if (!defined($pid = fork())) { # parent process, fork() failure } elsif ($pid == 0) { # child process, successful fork() } elsif ($justSomeVar == 1) { # parent process, successful fork() } else { # parent process, successful fork() }
      is the way to go?
Re: mysterious fork() failure
by Zaxo (Archbishop) on Jan 05, 2002 at 03:51 UTC

    The possible reasons for this are in the code you don't show. When you fork, you cannot know whether the child or parent runs first. If the parent runs first, and exits immediately, the child will be killed by the system's init process before it runs. Be sure to call wait() before exiting the parent. You should call exit() at the end of the child's code.

    # create new directory here if ( !defined( $pid = fork() ) ) { # log fork() failure here # remove directory here } elsif ($pid == 0) { # remove directory here exit 0; } wait if $pid;

    Update: Fixed pid logic according to dws's prescription

    After Compline,
    Zaxo

      "...the child will be killed by the system's init process before it runs." is not true in Unix systems.

      If the parent exits/dies before the child, init will become its parent and wait() for it.