1--TEST--
2Bug #60120 proc_open hangs with stdin/out with >2048 bytes
3--FILE--
4<?php
5error_reporting(E_ALL);
6
7$file = preg_replace(
8    "~\.phpt?$~", ".io.php", __FILE__);
9
10file_put_contents($file, <<<TMPFILE
11<?php
12\$input = stream_get_contents(STDIN);
13
14if (\$input) {
15    fwrite(STDOUT, \$input);
16    fwrite(STDERR, \$input);
17}
18?>
19TMPFILE
20);
21
22$command = sprintf("%s -n %s", PHP_BINARY, $file);
23
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
40if (!is_resource($process)) {
41    die(sprintf(
42        "could not open process \"%s\"",
43        $command));
44}
45
46fwrite($pipes[0], str_repeat('*', 10000));
47fclose($pipes[0]);
48
49stream_set_blocking($pipes[1], false);
50stream_set_blocking($pipes[2], false);
51
52$buffers = [
53    1 => "",
54    2 => ""
55];
56
57do {
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);
66        }
67        break;
68    }
69
70    foreach ($r as $ready) {
71        $buffers[
72            array_search($ready, $pipes)
73        ] .= fread($ready, 8192);
74    }
75
76    if (strlen($buffers[1]) === 10000 &&
77        strlen($buffers[2]) === 10000) {
78        break;
79    }
80} while (1);
81
82var_dump(
83    $buffers[1],
84    $buffers[2],
85    fread($pipes[1], 1),
86    fread($pipes[2], 1));
87
88fclose($pipes[1]);
89fclose($pipes[2]);
90?>
91--CLEAN--
92<?php
93$file = preg_replace("~\.clean\.php$~", ".io.php", __FILE__);
94unlink($file);
95?>
96--EXPECTF--
97string(10000) "%s"
98string(10000) "%s"
99string(0) ""
100string(0) ""
101