From 7b63428698bd7c50c7adaae7a3a98fe532b7b8f8 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Sun, 26 Aug 2012 15:13:51 +0200 Subject: [PATCH] [Process] Add workaround for PHP's internal sigchild failing to return proper exit codes --- src/Symfony/Component/Process/Process.php | 25 ++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/Process/Process.php b/src/Symfony/Component/Process/Process.php index 9cd7c78d900d..4dfd16f1f4af 100644 --- a/src/Symfony/Component/Process/Process.php +++ b/src/Symfony/Component/Process/Process.php @@ -39,6 +39,7 @@ class Process private $timeout; private $options; private $exitcode; + private $fallbackExitcode; private $processInformation; private $stdout; private $stderr; @@ -211,7 +212,13 @@ public function start($callback = null) ); $descriptors = array(array('pipe', 'r'), $this->fileHandles[self::STDOUT], array('pipe', 'w')); } else { - $descriptors = array(array('pipe', 'r'), array('pipe', 'w'), array('pipe', 'w')); + $descriptors = array( + array('pipe', 'r'), // stdin + array('pipe', 'w'), // stdout + array('pipe', 'w'), // stderr + array('pipe', 'w') // last exit code is output on the fourth pipe and caught to work around --enable-sigchild + ); + $this->commandline = '('.$this->commandline.') 3>/dev/null; echo $? >&3'; } $commandline = $this->commandline; @@ -336,8 +343,14 @@ public function wait($callback = null) foreach ($r as $pipe) { $type = array_search($pipe, $this->pipes); $data = fread($pipe, 8192); + if (strlen($data) > 0) { - call_user_func($callback, $type == 1 ? self::OUT : self::ERR, $data); + // last exit code is output and caught to work around --enable-sigchild + if (3 == $type) { + $this->fallbackExitcode = (int) $data; + } else { + call_user_func($callback, $type == 1 ? self::OUT : self::ERR, $data); + } } if (false === $data || feof($pipe)) { fclose($pipe); @@ -363,7 +376,13 @@ public function wait($callback = null) throw new \RuntimeException(sprintf('The process stopped because of a "%s" signal.', $this->processInformation['stopsig'])); } - return $this->exitcode = $this->processInformation['running'] ? $exitcode : $this->processInformation['exitcode']; + $this->exitcode = $this->processInformation['running'] ? $exitcode : $this->processInformation['exitcode']; + + if (-1 == $this->exitcode && null !== $this->fallbackExitcode) { + $this->exitcode = $this->fallbackExitcode; + } + + return $this->exitcode; } /**