2

I get wrong exit code from waitpid and I can't figure out why. Could someone give me some ideas?

Here what I do:

  1. I start my child process with open2
  2. then I wait for it to finish with waitpid
  3. get exit code using $?

It always returns with -1 no mater what I return from child process. I check with VS debugger that my program returns an exit code of 0. VS says something like this:

The program '[3256] Test.exe: Native' has exited with code 0 (0x0).

I made sure that pids match.

Any ideas?

brian d foy
  • 129,424
  • 31
  • 207
  • 592
Paulius Liekis
  • 1,676
  • 3
  • 18
  • 26
  • 2
    Could you post your perl code, using "sleep" instead of your program? –  Dec 30 '09 at 15:17

4 Answers4

7

I just figured it out. waitpid has 3 stages:

 1. process is running:    waitpid returns 0;   $? is -1
 2. process is exiting:    waitpid returns pid; $? is actual exit code
 3. process doesn't exist: waitpid returns -1;  $? is -1

so when doing something like while(waitpid($pid, WNOHANG) >= 0) exit code must be retrieved once cycle before that.

Paulius Liekis
  • 1,676
  • 3
  • 18
  • 26
3

From the waitpid man page:

Note that on some systems, a return value of "-1" could mean that child processes are being automatically reaped. See perlipc for details, and for other examples.

Brad Gilbert
  • 33,846
  • 11
  • 78
  • 129
Paul Tomblin
  • 179,021
  • 58
  • 319
  • 408
0

Rather than using waitpid, you should just close the filehandle. (I assume the "open2" in your question is a typo, and you meant "open")

William Pursell
  • 204,365
  • 48
  • 270
  • 300
  • 4
    open2 (see IPC::Open2) is a call that allows you to send input to and receive output from the same program – mob Dec 30 '09 at 15:29
0

Works for me (Windows):

use IPC::Open3;
use POSIX ':sys_wait_h';
use Time::HiRes;

$|++;

my ($fin, $fh, $pid);
$pid = open3($fin, $fh, 0, 'ping', '8.8.8.8') or die('error');

my @lines = ();
while (1) {
    while (my $line = <$fh>) {
        push(@lines, $line);
        print('+');
    }
    print("\nret: `$?`\n"), last if waitpid($pid, WNOHANG) <= 0;
    Time::HiRes::usleep(100000);
    $fh->clearerr();
}
waitpid($pid, 0);
print("\nret: `$?`\n");

Will output:

++++++++++++
ret: `-1`

ret: `0`
Dmitry Sokolov
  • 3,118
  • 1
  • 30
  • 35