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

I have an all perl version of FCGI that I made for work called ACGI... seems to work fine. However. I have an ACGI instance that forks child processes, and I put in code to check their exit values using waitpid and $?

When I have freshly started the ACGI, the first waitpid says the exit value was 0 (should be 1), all subsequent waitpids return 255 (should be 0). Any time after that they are all 255

As far as I see there are no end blocks screwing up the value, and an END block I specially put in at the end shows the proper exit values

The ACGI code that I am running is itself a child of a parent ACGI process, so I am thinking that maybe the dual level of forks is the problem, but it doesn't seem that it should be. But as the tests below show, the outer fork does seem to confuse the issue

The box in question is solaris 2.7, with perl 5.6.1...

UPDATE My bad on the test code... see bluto's messages... still have the real problem, tho. The following example is useless

when I run the following one-liner
perl -e 'if(fork){if(fork){waitpid(-1,undef);print"-- ",$?>>8,"\n";}else{exit 4}}'
I get random responses... either 4 or 0... no pattern.

On my debian box with 5.8.2, I always get 4...

and on my redhat box at work with 5.8.0 I always get 0...

Am I going crazy? Did I find a bug? Can I make this work somehow?

UPDATE

ARGH! There WAS and END block and it had system calls in it... damn legacy code full of requires...

                - Ant
                - Some of my best work - (1 2 3)

Replies are listed 'Best First'.
Re: Waitpid Woes
by Zaxo (Archbishop) on Dec 17, 2003 at 19:39 UTC

    On the one-liner, you are kicking out two child processes from the parent. Here's the code with indentation and decorations,

    if (fork) { #in parent if (fork) { #in parent still waitpid -1, undef; print "-- ", $?>>8, "\n"; } else { # in second child exit 4; } } # else ??? # parent and first child drop off the end
    Unix does not guarantee the order of execution of parent and child. If the parent runs first, the second child may exit 4 before the first child does a normal exit by falling off the end of the program.

    There is a good chance of your one-liner leaving zombie the child that waitpid didn't see. I/O generally takes more than one timeslice, so the remaining child is apt to end its brief life during print and shamble about waiting for somebody to read its exit status.

    After Compline,
    Zaxo

      Yeah... unfortunately, this solves the mystery of my test, but not the problem with the real code. That is happening in a child process.

                      - Ant
                      - Some of my best work - (1 2 3)

Re: Waitpid Woes
by bluto (Curate) on Dec 17, 2003 at 19:20 UTC
    You are forking two children from one parent and then seeing the exit code from the first one that happens to die. To see this, try adding an 'else {exit 2}' to the outer fork and try again.
      Well... but the waitpid is in the second fork... shouldn't it only see its one child?

      I had assumed that the waitpid would only catch your direct children.

                      - Ant
                      - Some of my best work - (1 2 3)

        No, the same parent is forking both children. When you say 'if (fork)', the code in the first part of the if is the parent code, the part in the 'else' is the child.