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

Below code work but after executing command in fork child its returning commands exist value but parents is not getting childs correct exits value, either success or failed parents is always getting '0' as $? is which means success! Can anyone suggest me better way of doing this?
my $pid = fork(); if($pid == 0) { my $log = '/home/tart/tmp/log.log'; open(CLOG, ">>$log") || die "$0: can't open '$log': $!\n"; open(STDOUT, ">&CLOG")|| die "$0: Can't remap STDOUT: $!\n"; open(STDERR, ">&CLOG")|| die "$0: Can't remap STDERR: $!\n"; @systemOut = `$command`; print CLOG "@systemOut"; close CLOG; exit $?; } else { while (waitpid($pid, WNOHANG) == 0) { sleep 1; my $upTime = time; my $diffTime = $upTime - $sTime; $diffTime = int($diffTime/60); verbose($configHR, "Processing...since $diffTime Min!") if($diffTime != $regVal); $regVal = $diffTime; } } if($? == 0) { print LOG "Status: Success\n"; return 1; } print LOG "Status: Failed While Executing $command\n";
Thanks, -------Updates-------
Hi,

My Above listed fork and execution process is in the subroutine which is first evaluated by eval.
To be more specific, First eval evaluate the subroutine name '&execute($cmd)' then inside the execute subroutine fork runs and in child process commands get executed as in first posted code,
So, just wondering does eval does any thing in forking process? example,
#$sub is subroutine name. #for example: $sub = '&execute'. my $stmt = '$rv = '. $sub; eval $stmt; if($@) { print $@, "\n"; } sub execute { my $pid = fork(); if($pid == 0) { my $log = '/home/tart/tmp/log.log'; open(CLOG, ">>$log") || die "$0: can't open '$log': $!\n"; open(STDOUT, ">&CLOG")|| die "$0: Can't remap STDOUT: $!\n"; open(STDERR, ">&CLOG")|| die "$0: Can't remap STDERR: $!\n"; @systemOut = `$command`; print CLOG "@systemOut"; close CLOG; exit $?; } else { while (waitpid($pid, WNOHANG) == 0) { sleep 1; my $upTime = time; my $diffTime = $upTime - $sTime; $diffTime = int($diffTime/60); verbose($configHR, "Processing...since $diffTime Min!") if($diffTime != $regVal); $regVal = $diffTime; } } if($? == 0) { print LOG "Status: Success\n"; return 1; } print LOG "Status: Failed While Executing $command\n"; }
Thanks,

Replies are listed 'Best First'.
Re: fork child exist value
by ikegami (Patriarch) on Oct 27, 2010 at 06:44 UTC

    Works for me. Are you sure your child is exiting with something other than zero?

    $ cat a.pl use strict; use warnings; use POSIX qw( WNOHANG ); my $pid = fork(); if ($pid == 0) { sleep(5); exit $ARGV[0]; } while (waitpid($pid, WNOHANG) == 0) { sleep 1; print time(), "\n"; } print "$?\n";
    $ perl a.pl 123 1288161738 1288161739 1288161740 1288161741 1288161742 31488

    (31488 == 123 * 256)