>>>>> "SR" == Steve Revilak <[EMAIL PROTECTED]> writes:


  SR> sub main() {
  SR>      my @kids = ();
  SR>       for (1..10) {
  SR>           my $fh = anon_fh();

i know this is just an example script but i have some general comments
anyway as well as a possible explanation for your issue.

you can use lexical handles with open and it will autogenerate one for
you. or if you must get one on your own, use Symbol::gensym. no need to
make a sub to get one.


  SR>           my $pid = open($fh, "-|");

you should also check for !defined $pid to see if the fork failed.

  SR>           if ($pid == 0) {
  SR>               kid_stuff();
  SR>           }
  SR>           else {
  SR>               push(@kids, [ $pid, $fh ]);
  SR>           }
  SR>       }

  SR>      foreach my $kid (@kids) {
  SR>          my ($pid, $fh) = @$kid;
  SR>          my $wpid = waitpid($pid, 0);

  SR>          chomp(my $output = <$fh>);
  SR>          print("DONE: PID=$wpid, status=$? output=$output\n");
  SR>          close($fh);
  SR>       }
  SR> }

  SR> sub kid_stuff() {
  SR>       exec("echo kid");
  SR> }

just 'print "kid"; exit' would do the same.

  SR>               my $handle = IO::Handle->new();     # new
  SR>               $handle->fdopen(fileno($fh), "r");  # new

my guess is that the info associated with $fh that is used by waitpid is
lost there. fileno gets a raw file number which is then reopened as a
perl handle. so it has no association with the forked handle $fh. did
you print out the pids before you waited on them? a -1 return from
waitpid means there is no kid with that pid. possibly the kids were not
done or were reaped some other way (odd if that).

  SR>               push(@kids, [ $pid, $handle ]);
  SR>           }
  SR>       }

  SR>      foreach my $kid (@kids) {
  SR>          my ($pid, $fh) = @$kid;
  SR>          my $wpid = waitpid($pid, 0);

  SR>          chomp(my $output = $fh->getline());      # new
  SR>          print("DONE: PID=$wpid, status=$? output=$output\n");
  SR>          $fh->close();                            # new

forked children don't exit until their handles are closed. try
reordering those lines to read the data first, then close, and then
waitpid. that is the proper order for those calls.

  SR> Clearly, the parent was able to read the child process's stdout; but,
  SR> we effectively lost $? and the return value of waitpid.

but the kids aren't done until they have their handles closed. you kept
TWO handles open, the original and the cloned one with fdopen. this may
be keeping the kid running until your parent exits so the waitpid
fails. try my reorder thing and see if that works. i could be grasping
at straws since my ACKing cold is affecting my 3 living neurons.

uri

-- 
Uri Guttman  ------  [EMAIL PROTECTED]  --------  http://www.sysarch.com --
-----  Perl Code Review , Architecture, Development, Training, Support ------
--------- Free Perl Training --- http://perlhunter.com/college.html ---------
---------  Gourmet Hot Cocoa Mix  ----  http://bestfriendscocoa.com ---------

_______________________________________________
Boston-pm mailing list
[email protected]
http://mail.pm.org/mailman/listinfo/boston-pm

Reply via email to