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