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

I have a perl script which is attempting to perform an ldapsearch in child processes and return an exit code dependent on the result. The ldapsearch can hang which is why a child is used.

The issue I'm having is that the exit code from the child is not being returned (or probably I'm not extracting it properly) to the parent via waitpid.

Incomplete code fragment below

foreach $serv ( @serv ) { $command="/bin/ldapsearch -h $serv -b '' -s base 'obje +ctclass=*' |"; DEBUG_msg("Forking child to run $command"); $pid=fork(); if ( ! defined $pid ) { ERROR_exit("Unable to fork process for $serv i +n $dmn"); } elsif ( $pid == 0 ) { # We are the child - run the LDAP command, fin +d ldapServiceName and # compare the domain with the one we're checki +ng and then exit # with the appropriate status ... open(INP,$command) or ERROR_exit("Unable to ru +n LDAP search $!"); while( $data=<INP> ) { chomp($data); (@words)=split(/:/,$data); if ( $words[0] eq "ldapServiceName" ) +{ # Now have the info - extract +domain ... $words[2]=~ s/.*\@//; $words[2]= lc($words[2]); DEBUG_msg(" Found $words[2] f +or $serv"); if ( $words[2] eq $dmn ) { DEBUG_msg(" matches e +xpected domain - exit OK"); exit 5; } else { DEBUG_msg(" domain mi +smatch - exit FAIL"); exit 2; } } } close(INP); # Didnt find the data - exit from child with e +rror exit 3; } else { # Still in parent $pid the PID of the child DEBUG_msg(" Child process $pid"); $pid_list{$pid}=$serv.":".$dmn; } } foreach $pid ( keys %pid_list ) { DEBUG_msg("Checking state of $pid"); $res=waitpid($pid,WNOHANG); $rc=$res >> 8; my $tst=$res/256; print STDERR "PID $pid res $res rc $rc test $tst ";

The status code from the child, which I would exppect to be 5, varies each time the process is run - which is why I think I'm doing something wrong - sample output below

Debug: PID 20670 Child process 20692 Debug: PID 20670 Child process 20694 Debug: PID 20670 Child process 20697 Debug: PID 20670 Child process 20699 Debug: PID 20670 Child process 20702 Debug: PID 20670 Child process 20705 Debug: PID 20694 matches expected domain - exit OK Debug: PID 20702 matches expected domain - exit OK Debug: PID 20699 matches expected domain - exit OK Debug: PID 20670 Checking state of 20692 PID 20692 res 0 rc 0 test 0 Debug: PID 20670 Checking state of 20702 PID 20702 res 20702 rc 80 tes +t 80 Debug: PID 20670 Checking state of 20697 PID 20697 res 0 rc 0 test 0 Debug: PID 20670 Checking state of 20694 PID 20694 res 20694 rc 80 tes +t 80 Debug: PID 20670 Checking state of 20699 PID 20699 res 20699 rc 80 tes +t 80 Debug: PID 20670 Checking state of 20705 PID 20705 res 0 rc 0 test 0

This is perl, v5.8.4 built for sun4-solaris-64int

Replies are listed 'Best First'.
Re: how do I extract status from the response of waitpid ?
by dave_the_m (Monsignor) on Aug 14, 2015 at 11:34 UTC
    waitpid returns the PID of the reaped child, not its exit status. waitpid sets the child's status in $?

    Dave.

Re: how do I extract status from the response of waitpid ?
by pme (Monsignor) on Aug 14, 2015 at 11:38 UTC
    The exit code is '$? >> 8', not the returned value. $? is documented in perlvar man page.
      $? >> 8 is only meaningful if waitpid returned a value greater than zero and if $? != -1 && ($? & 0x7F) == 0.