pajoye Mon, 24 Oct 2011 12:39:55 +0000 Revision: http://svn.php.net/viewvc?view=revision&revision=318366
Log: - fixed bug #60120, proc_open's streams may hang with stdin/out/err when the data exceeds or is equal to 2048 bytes Bug: https://bugs.php.net/60120 (Assigned) proc_open hangs with stdin/out with 2048+ bytes Changed paths: U php/php-src/branches/PHP_5_3/NEWS U php/php-src/branches/PHP_5_3/ext/standard/proc_open.c A php/php-src/branches/PHP_5_3/ext/standard/tests/file/bug60120.phpt U php/php-src/branches/PHP_5_4/NEWS U php/php-src/branches/PHP_5_4/ext/standard/proc_open.c A php/php-src/branches/PHP_5_4/ext/standard/tests/file/bug60120.phpt U php/php-src/trunk/ext/standard/proc_open.c A php/php-src/trunk/ext/standard/tests/file/bug60120.phpt
Modified: php/php-src/branches/PHP_5_3/NEWS =================================================================== --- php/php-src/branches/PHP_5_3/NEWS 2011-10-24 12:34:44 UTC (rev 318365) +++ php/php-src/branches/PHP_5_3/NEWS 2011-10-24 12:39:55 UTC (rev 318366) @@ -3,6 +3,8 @@ ?? ??? 2011, PHP 5.3.9 - 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) . Fixed bug #60019 (Function time_nanosleep() is undefined on OS X). (Ilia) . Fixed bug #55798 (serialize followed by unserialize with numeric object prop. gives integer prop). (Gustavo) Modified: php/php-src/branches/PHP_5_3/ext/standard/proc_open.c =================================================================== --- php/php-src/branches/PHP_5_3/ext/standard/proc_open.c 2011-10-24 12:34:44 UTC (rev 318365) +++ php/php-src/branches/PHP_5_3/ext/standard/proc_open.c 2011-10-24 12:39:55 UTC (rev 318366) @@ -451,7 +451,7 @@ /* {{{ 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" Added: php/php-src/branches/PHP_5_3/ext/standard/tests/file/bug60120.phpt =================================================================== --- php/php-src/branches/PHP_5_3/ext/standard/tests/file/bug60120.phpt (rev 0) +++ php/php-src/branches/PHP_5_3/ext/standard/tests/file/bug60120.phpt 2011-10-24 12:39:55 UTC (rev 318366) @@ -0,0 +1,74 @@ +--TEST-- +Bug #60120 (proc_open hangs when data in stdin/out/err is getting larger or equal to 2048) +--SKIPIF-- +<?php +if (substr(PHP_OS, 0, 3) != 'WIN') { + die('skip only for Windows'); +} +$php = getenv('TEST_PHP_EXECUTABLE'); +if (!$php) { + die("No php executable defined\n"); +} +?> +--FILE-- +<?php + +error_reporting(E_ALL); + +$php = getenv('TEST_PHP_EXECUTABLE'); +if (!$php) { + die("No php executable defined\n"); +} +$cmd = 'php -r "fwrite(STDOUT, $in = file_get_contents(\'php://stdin\')); fwrite(STDERR, $in);"'; +$descriptors = array(array('pipe', 'r'), array('pipe', 'w'), array('pipe', 'w')); +$stdin = str_repeat('*', 1024 * 16) . '!'; +$stdin = str_repeat('*', 2049 ); + +$options = array_merge(array('suppress_errors' => 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. Modified: php/php-src/branches/PHP_5_4/NEWS =================================================================== --- php/php-src/branches/PHP_5_4/NEWS 2011-10-24 12:34:44 UTC (rev 318365) +++ php/php-src/branches/PHP_5_4/NEWS 2011-10-24 12:39:55 UTC (rev 318366) @@ -9,6 +9,10 @@ (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) Modified: php/php-src/branches/PHP_5_4/ext/standard/proc_open.c =================================================================== --- php/php-src/branches/PHP_5_4/ext/standard/proc_open.c 2011-10-24 12:34:44 UTC (rev 318365) +++ php/php-src/branches/PHP_5_4/ext/standard/proc_open.c 2011-10-24 12:39:55 UTC (rev 318366) @@ -377,7 +377,7 @@ /* {{{ 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" Added: php/php-src/branches/PHP_5_4/ext/standard/tests/file/bug60120.phpt =================================================================== --- php/php-src/branches/PHP_5_4/ext/standard/tests/file/bug60120.phpt (rev 0) +++ php/php-src/branches/PHP_5_4/ext/standard/tests/file/bug60120.phpt 2011-10-24 12:39:55 UTC (rev 318366) @@ -0,0 +1,74 @@ +--TEST-- +Bug #60120 (proc_open hangs when data in stdin/out/err is getting larger or equal to 2048) +--SKIPIF-- +<?php +if (substr(PHP_OS, 0, 3) != 'WIN') { + die('skip only for Windows'); +} +$php = getenv('TEST_PHP_EXECUTABLE'); +if (!$php) { + die("No php executable defined\n"); +} +?> +--FILE-- +<?php + +error_reporting(E_ALL); + +$php = getenv('TEST_PHP_EXECUTABLE'); +if (!$php) { + die("No php executable defined\n"); +} +$cmd = 'php -r "fwrite(STDOUT, $in = file_get_contents(\'php://stdin\')); fwrite(STDERR, $in);"'; +$descriptors = array(array('pipe', 'r'), array('pipe', 'w'), array('pipe', 'w')); +$stdin = str_repeat('*', 1024 * 16) . '!'; +$stdin = str_repeat('*', 2049 ); + +$options = array_merge(array('suppress_errors' => 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. Modified: php/php-src/trunk/ext/standard/proc_open.c =================================================================== --- php/php-src/trunk/ext/standard/proc_open.c 2011-10-24 12:34:44 UTC (rev 318365) +++ php/php-src/trunk/ext/standard/proc_open.c 2011-10-24 12:39:55 UTC (rev 318366) @@ -377,7 +377,7 @@ /* {{{ 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" Added: php/php-src/trunk/ext/standard/tests/file/bug60120.phpt =================================================================== --- php/php-src/trunk/ext/standard/tests/file/bug60120.phpt (rev 0) +++ php/php-src/trunk/ext/standard/tests/file/bug60120.phpt 2011-10-24 12:39:55 UTC (rev 318366) @@ -0,0 +1,74 @@ +--TEST-- +Bug #60120 (proc_open hangs when data in stdin/out/err is getting larger or equal to 2048) +--SKIPIF-- +<?php +if (substr(PHP_OS, 0, 3) != 'WIN') { + die('skip only for Windows'); +} +$php = getenv('TEST_PHP_EXECUTABLE'); +if (!$php) { + die("No php executable defined\n"); +} +?> +--FILE-- +<?php + +error_reporting(E_ALL); + +$php = getenv('TEST_PHP_EXECUTABLE'); +if (!$php) { + die("No php executable defined\n"); +} +$cmd = 'php -r "fwrite(STDOUT, $in = file_get_contents(\'php://stdin\')); fwrite(STDERR, $in);"'; +$descriptors = array(array('pipe', 'r'), array('pipe', 'w'), array('pipe', 'w')); +$stdin = str_repeat('*', 1024 * 16) . '!'; +$stdin = str_repeat('*', 2049 ); + +$options = array_merge(array('suppress_errors' => 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.
-- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php