xref: /PHP-8.1/ext/standard/tests/file/bug60120.phpt (revision dd44a933)
1--TEST--
2Bug #60120 (proc_open hangs when data in stdin/out/err is getting larger or equal to 2048)
3--SKIPIF--
4<?php
5$php = getenv('TEST_PHP_EXECUTABLE');
6if (!$php) {
7    die("skip No php executable defined\n");
8}
9if (PHP_OS_FAMILY === 'Windows') die('skip not for Windows');
10?>
11--FILE--
12<?php
13
14error_reporting(E_ALL);
15
16$php = getenv('TEST_PHP_EXECUTABLE');
17if (!$php) {
18    die("No php executable defined\n");
19}
20$cmd = $php . ' -r "\$in = file_get_contents(\'php://stdin\'); fwrite(STDOUT, \$in); fwrite(STDERR, \$in);"';
21$descriptors = array(array('pipe', 'r'), array('pipe', 'w'), array('pipe', 'w'));
22$stdin = str_repeat('*', 2049 );
23
24$options = array_merge(array('suppress_errors' => true, 'bypass_shell' => false));
25$process = proc_open($cmd, $descriptors, $pipes, getcwd(), array(), $options);
26
27foreach ($pipes as $pipe) {
28    stream_set_blocking($pipe, false);
29}
30$writePipes = array($pipes[0]);
31$stdinLen = strlen($stdin);
32$stdinOffset = 0;
33
34unset($pipes[0]);
35
36$procOutput = [];
37while ($pipes || $writePipes) {
38    $r = $pipes;
39    $w = $writePipes;
40    $e = null;
41    $n = stream_select($r, $w, $e, 60);
42
43    if (false === $n) {
44        break;
45    } elseif ($n === 0) {
46        proc_terminate($process);
47
48    }
49    if ($w) {
50        $written = fwrite($writePipes[0], substr($stdin, $stdinOffset), 8192);
51        if (false !== $written) {
52            $stdinOffset += $written;
53        } else {
54            die('Failed to write to pipe');
55        }
56        if ($stdinOffset >= $stdinLen) {
57            fclose($writePipes[0]);
58            $writePipes = null;
59        }
60    }
61
62    foreach ($r as $pipe) {
63        $type = array_search($pipe, $pipes);
64        $data = fread($pipe, 8192);
65        if (feof($pipe)) {
66            fclose($pipe);
67            unset($pipes[$type]);
68        } elseif (false === $data) {
69            die('Failed to read from pipe');
70        } else {
71            $procOutput[$type] = ($procOutput[$type] ?? '') . $data;
72        }
73    }
74}
75foreach ($procOutput as $output) {
76    if ($output !== $stdin) {
77        die('Output does not match input: ' . $output);
78    }
79}
80echo "OK.";
81?>
82--EXPECT--
83OK.
84