|
1 | 1 | --TEST--
|
2 |
| -Bug #60120 proc_open hangs with stdin/out with 2048+ bytes |
| 2 | +Bug #60120 proc_open hangs with stdin/out with >2048 bytes |
3 | 3 | --FILE--
|
4 | 4 | <?php
|
5 | 5 | error_reporting(E_ALL);
|
6 | 6 |
|
7 |
| -if (substr(PHP_OS, 0, 3) == 'WIN') { |
8 |
| - $cmd = PHP_BINARY . ' -n -r "fwrite(STDOUT, $in = file_get_contents(\'php://stdin\')); fwrite(STDERR, $in);"'; |
9 |
| -} else { |
10 |
| - $cmd = PHP_BINARY . ' -n -r \'fwrite(STDOUT, $in = file_get_contents("php://stdin")); fwrite(STDERR, $in);\''; |
| 7 | +$file = preg_replace( |
| 8 | + "~\.phpt?$~", ".io.php", __FILE__); |
| 9 | + |
| 10 | +file_put_contents($file, <<<TMPFILE |
| 11 | +<?php |
| 12 | +\$input = stream_get_contents(STDIN); |
| 13 | +
|
| 14 | +if (\$input) { |
| 15 | + fwrite(STDOUT, \$input); |
| 16 | + fwrite(STDERR, \$input); |
11 | 17 | }
|
12 |
| -$descriptors = array(array('pipe', 'r'), array('pipe', 'w'), array('pipe', 'w')); |
13 |
| -$stdin = str_repeat('*', 1024 * 16) . '!'; |
14 |
| -$stdin = str_repeat('*', 2049 ); |
| 18 | +?> |
| 19 | +TMPFILE |
| 20 | +); |
15 | 21 |
|
16 |
| -$options = array_merge(array('suppress_errors' => true, 'bypass_shell' => false)); |
17 |
| -$process = proc_open($cmd, $descriptors, $pipes, getcwd(), array(), $options); |
| 22 | +$command = sprintf("%s -n %s", PHP_BINARY, $file); |
18 | 23 |
|
19 |
| -foreach ($pipes as $pipe) { |
20 |
| - stream_set_blocking($pipe, false); |
| 24 | +$process = proc_open( |
| 25 | + $command, |
| 26 | + [ |
| 27 | + ['pipe', 'r'], |
| 28 | + ['pipe', 'w'], |
| 29 | + ['pipe', 'w'] |
| 30 | + ], |
| 31 | + $pipes, |
| 32 | + getcwd(), |
| 33 | + [], |
| 34 | + [ |
| 35 | + 'suppress_errors' => true, |
| 36 | + 'bypass_shell' => false |
| 37 | + ] |
| 38 | +); |
| 39 | + |
| 40 | +if (!is_resource($process)) { |
| 41 | + die(sprintf( |
| 42 | + "could not open process \"%s\"", |
| 43 | + $command)); |
21 | 44 | }
|
22 |
| -$writePipes = array($pipes[0]); |
23 |
| -$stdinLen = strlen($stdin); |
24 |
| -$stdinOffset = 0; |
25 | 45 |
|
26 |
| -unset($pipes[0]); |
| 46 | +fwrite($pipes[0], str_repeat('*', 10000)); |
| 47 | +fclose($pipes[0]); |
27 | 48 |
|
28 |
| -while ($pipes || $writePipes) { |
29 |
| - $r = $pipes; |
30 |
| - $w = $writePipes; |
31 |
| - $e = null; |
32 |
| - $n = stream_select($r, $w, $e, 60); |
| 49 | +stream_set_blocking($pipes[1], false); |
| 50 | +stream_set_blocking($pipes[2], false); |
33 | 51 |
|
34 |
| - if (false === $n) { |
35 |
| - break; |
36 |
| - } elseif ($n === 0) { |
37 |
| - proc_terminate($process); |
| 52 | +$buffers = [ |
| 53 | + 1 => "", |
| 54 | + 2 => "" |
| 55 | +]; |
38 | 56 |
|
39 |
| - } |
40 |
| - if ($w) { |
41 |
| - $written = fwrite($writePipes[0], substr($stdin, $stdinOffset), 8192); |
42 |
| - if (false !== $written) { |
43 |
| - $stdinOffset += $written; |
44 |
| - } |
45 |
| - if ($stdinOffset >= $stdinLen) { |
46 |
| - fclose($writePipes[0]); |
47 |
| - $writePipes = null; |
| 57 | +do { |
| 58 | + $r = [$pipes[1], $pipes[2]]; |
| 59 | + $w = []; |
| 60 | + $e = []; |
| 61 | + $s = stream_select($r, $w, $e, 60); |
| 62 | + |
| 63 | + if (!$s) { |
| 64 | + if ($s === false) { |
| 65 | + proc_terminate($process); |
48 | 66 | }
|
| 67 | + break; |
49 | 68 | }
|
50 | 69 |
|
51 |
| - foreach ($r as $pipe) { |
52 |
| - $type = array_search($pipe, $pipes); |
53 |
| - $data = fread($pipe, 8192); |
54 |
| - var_dump($data); |
55 |
| - if (false === $data || feof($pipe)) { |
56 |
| - fclose($pipe); |
57 |
| - unset($pipes[$type]); |
58 |
| - } |
| 70 | + foreach ($r as $ready) { |
| 71 | + $buffers[ |
| 72 | + array_search($ready, $pipes) |
| 73 | + ] .= fread($ready, 8192); |
59 | 74 | }
|
60 |
| -} |
61 | 75 |
|
| 76 | + if (strlen($buffers[1]) === 10000 && |
| 77 | + strlen($buffers[2]) === 10000) { |
| 78 | + break; |
| 79 | + } |
| 80 | +} while (1); |
| 81 | + |
| 82 | +var_dump( |
| 83 | + $buffers[1], |
| 84 | + $buffers[2], |
| 85 | + fread($pipes[1], 1), |
| 86 | + fread($pipes[2], 1)); |
62 | 87 |
|
| 88 | +fclose($pipes[1]); |
| 89 | +fclose($pipes[2]); |
63 | 90 | ?>
|
64 |
| -===DONE=== |
65 | 91 | --EXPECTF--
|
66 |
| -string(2049) "%s" |
67 |
| -string(2049) "%s" |
| 92 | +string(10000) "%s" |
| 93 | +string(10000) "%s" |
68 | 94 | string(0) ""
|
69 | 95 | string(0) ""
|
70 |
| -===DONE=== |
| 96 | +--CLEAN-- |
| 97 | +unlink($file); |
0 commit comments