If you are, like me, tired of the buggy way proc_open handles streams and exit codes; this example demonstrate the power of pcntl, posix and some simple output redirection:
<?php
$outpipe = '/tmp/outpipe';
$inpipe = '/tmp/inpipe';
posix_mkfifo($inpipe, 0600);
posix_mkfifo($outpipe, 0600);
$pid = pcntl_fork();
if($pid) {
$in = fopen($inpipe, 'w');
fwrite($in, "A message for the inpipe reader\n");
fclose($in);
$out = fopen($outpipe, 'r');
while(!feof($out)) {
echo "From out pipe: " . fgets($out) . PHP_EOL;
}
fclose($out);
pcntl_waitpid($pid, $status);
if(pcntl_wifexited($status)) {
echo "Reliable exit code: " . pcntl_wexitstatus($status) . PHP_EOL;
}
unlink($outpipe);
unlink($inpipe);
}
else {
if($pid = pcntl_fork()) {
pcntl_exec('/bin/sh', array('-c', "printf 'A message for the outpipe reader' > $outpipe 2>&1 && exit 12"));
}
else {
pcntl_exec('/bin/sh', array('-c', "printf 'From in pipe: '; cat $inpipe"));
}
}
?>
Output:
From in pipe: A message for the inpipe reader
From out pipe: A message for the outpipe reader
Reliable exit code: 12