From c2405c0bbc288c97bd0057c1cd98ed68fdef8630 Mon Sep 17 00:00:00 2001 From: Andrej Hudec Date: Sun, 22 Apr 2012 21:52:08 +0200 Subject: [PATCH 1/2] fix hanging of unit tests on Windows --- src/Symfony/Component/Process/Process.php | 62 +++++++++++++++++++++-- 1 file changed, 59 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/Process/Process.php b/src/Symfony/Component/Process/Process.php index eed46a0c09..d3c14aa0b0 100644 --- a/src/Symfony/Component/Process/Process.php +++ b/src/Symfony/Component/Process/Process.php @@ -47,6 +47,9 @@ class Process private $process; private $status = self::STATUS_READY; + private $fileHandles; + private $readedBytes; + /** * Exit codes translation table. * @@ -195,7 +198,18 @@ class Process $this->stdout = ''; $this->stderr = ''; $callback = $this->buildCallback($callback); - $descriptors = array(array('pipe', 'r'), array('pipe', 'w'), array('pipe', 'w')); + + //Fix for PHP bug #51800: reading from STDOUT pipe hangs forever on Windows if the output is too big. + //Workaround for this problem is to use temporary files instead of pipes on Windows platform. + //@see https://bugs.php.net/bug.php?id=51800 + if (defined('PHP_WINDOWS_VERSION_BUILD')) { + $this->fileHandles = array( + self::STDOUT => tmpfile(), + ); + $descriptors = array(array('pipe', 'r'), $this->fileHandles[self::STDOUT], array('pipe', 'w')); + } else { + $descriptors = array(array('pipe', 'r'), array('pipe', 'w'), array('pipe', 'w')); + } $commandline = $this->commandline; @@ -255,6 +269,22 @@ class Process } } + if (defined('PHP_WINDOWS_VERSION_BUILD')) { + $fh = $this->fileHandles; + foreach ($fh as $type => $fileHandle) { + fseek($fileHandle, 0); + $data = fread($fileHandle, 8192); + $this->readedBytes[$type] = strlen($data); + if (strlen($data) > 0) { + call_user_func($callback, $type == 1 ? self::OUT : self::ERR, $data); + } + if (false === $data) { + fclose($fileHandle); + unset($this->fileHandles[$type]); + } + } + } + foreach ($r as $pipe) { $type = array_search($pipe, $this->pipes); $data = fread($pipe, 8192); @@ -288,7 +318,7 @@ class Process { $this->processInformation = proc_get_status($this->process); $callback = $this->buildCallback($callback); - while ($this->pipes) { + while ($this->pipes || (defined('PHP_WINDOWS_VERSION_BUILD') && $this->fileHandles)) { $r = $this->pipes; $w = null; $e = null; @@ -304,6 +334,22 @@ class Process throw new \RuntimeException('The process timed out.'); } + if (defined('PHP_WINDOWS_VERSION_BUILD')) { + $fh = $this->fileHandles; + foreach ($fh as $type => $fileHandle) { + fseek($fileHandle, $this->readedBytes[$type]); + $data = fread($fileHandle, 8192); + $this->readedBytes[$type] += strlen($data); + if (strlen($data) > 0) { + call_user_func($callback, $type == 1 ? self::OUT : self::ERR, $data); + } + if (false === $data) { + fclose($fileHandle); + unset($this->fileHandles[$type]); + } + } + } + foreach ($r as $pipe) { $type = array_search($pipe, $this->pipes); $data = fread($pipe, 8192); @@ -517,6 +563,13 @@ class Process $exitcode = proc_close($this->process); $this->exitcode = -1 === $this->processInformation['exitcode'] ? $exitcode : $this->processInformation['exitcode']; + + if (defined('PHP_WINDOWS_VERSION_BUILD')) { + foreach ($this->fileHandles as $fileHandle) { + fclose($fileHandle); + } + $this->fileHandles = array(); + } } $this->status = self::STATUS_TERMINATED; @@ -660,7 +713,10 @@ class Process protected function updateOutput() { - if (isset($this->pipes[self::STDOUT]) && is_resource($this->pipes[self::STDOUT])) { + if (defined('PHP_WINDOWS_VERSION_BUILD') && isset($this->fileHandles[self::STDOUT]) && is_resource($this->fileHandles[self::STDOUT])) { + fseek($this->fileHandles[self::STDOUT], $this->readedBytes[self::STDOUT]); + $this->addOutput(stream_get_contents($this->fileHandles[self::STDOUT])); + } elseif (isset($this->pipes[self::STDOUT]) && is_resource($this->pipes[self::STDOUT])) { $this->addOutput(stream_get_contents($this->pipes[self::STDOUT])); } } From e3296cb744bd8e2b1e6356065f5480343d3414a3 Mon Sep 17 00:00:00 2001 From: Andrej Hudec Date: Mon, 23 Apr 2012 00:05:10 +0200 Subject: [PATCH 2/2] fix php5.4 problem --- src/Symfony/Component/Process/Process.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/Process/Process.php b/src/Symfony/Component/Process/Process.php index d3c14aa0b0..47d00afacf 100644 --- a/src/Symfony/Component/Process/Process.php +++ b/src/Symfony/Component/Process/Process.php @@ -339,7 +339,12 @@ class Process foreach ($fh as $type => $fileHandle) { fseek($fileHandle, $this->readedBytes[$type]); $data = fread($fileHandle, 8192); - $this->readedBytes[$type] += strlen($data); + if(isset($this->readedBytes)) { + $this->readedBytes[$type] += strlen($data); + } else { + $this->readedBytes[$type] = strlen($data); + } + if (strlen($data) > 0) { call_user_func($callback, $type == 1 ? self::OUT : self::ERR, $data); }