From: Pierre Joye Date: Mon, 24 Oct 2011 12:39:55 +0000 (+0000) Subject: - fixed bug #60120, proc_open's streams may hang with stdin/out/err when the data... X-Git-Tag: php-5.4.0RC1~76 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=97076fa68e71c6afda4706a4f1f6d2a87ded6e26;p=php - fixed bug #60120, proc_open's streams may hang with stdin/out/err when the data exceeds or is equal to 2048 bytes --- diff --git a/NEWS b/NEWS index ab974183fc..83d1566909 100644 --- a/NEWS +++ b/NEWS @@ -9,6 +9,10 @@ PHP NEWS (Laruence) . Fixed bug #60115 (memory definitely lost in cli server). (Laruence) +- Core: + . Fixed bug #60120 (proc_open's streams may hang with stdin/out/err when + the data exceeds or is equal to 2048 bytes). (Pierre, Pascal Borreli) + 20 Oct 2011, PHP 5.4.0 beta2 - General improvements: . Improve the warning message of incompatible arguments. (Laruence) diff --git a/ext/standard/proc_open.c b/ext/standard/proc_open.c index c8ce705251..1caa56945d 100644 --- a/ext/standard/proc_open.c +++ b/ext/standard/proc_open.c @@ -377,7 +377,7 @@ PHP_FUNCTION(proc_get_status) /* {{{ handy definitions for portability/readability */ #ifdef PHP_WIN32 -# define pipe(pair) (CreatePipe(&pair[0], &pair[1], &security, 2048L) ? 0 : -1) +# define pipe(pair) (CreatePipe(&pair[0], &pair[1], &security, 0) ? 0 : -1) # define COMSPEC_NT "cmd.exe" diff --git a/ext/standard/tests/file/bug60120.phpt b/ext/standard/tests/file/bug60120.phpt new file mode 100644 index 0000000000..8915bb833c --- /dev/null +++ b/ext/standard/tests/file/bug60120.phpt @@ -0,0 +1,74 @@ +--TEST-- +Bug #60120 (proc_open hangs when data in stdin/out/err is getting larger or equal to 2048) +--SKIPIF-- + +--FILE-- + true, 'binary_pipes' => true, 'bypass_shell' => false)); +$process = proc_open($cmd, $descriptors, $pipes, getcwd(), array(), $options); + +foreach ($pipes as $pipe) { + stream_set_blocking($pipe, false); +} +$writePipes = array($pipes[0]); +$stdinLen = strlen($stdin); +$stdinOffset = 0; + +unset($pipes[0]); + +while ($pipes || $writePipes) { + $r = $pipes; + $w = $writePipes; + $e = null; + $n = stream_select($r, $w, $e, 60); + + if (false === $n) { + break; + } elseif ($n === 0) { + proc_terminate($process); + + } + if ($w) { + $written = fwrite($writePipes[0], (binary)substr($stdin, $stdinOffset), 8192); + if (false !== $written) { + $stdinOffset += $written; + } + if ($stdinOffset >= $stdinLen) { + fclose($writePipes[0]); + $writePipes = null; + } + } + + foreach ($r as $pipe) { + $type = array_search($pipe, $pipes); + $data = fread($pipe, 8192); + if (false === $data || feof($pipe)) { + fclose($pipe); + unset($pipes[$type]); + } + } +} +echo "OK."; +?> +--EXPECT-- +OK.