Skip to content

Commit 3852a35

Browse files
committed
This test is flaky, and some of it doesn't make sense.
I've refactored based on the original bug report, related bugs, and commits to php-src that were related to them. It is supposed to be testing windows specific behaviour related to non-blocking pipes, nevertheless the test runs everywhere.
1 parent cfdca10 commit 3852a35

File tree

1 file changed

+74
-47
lines changed

1 file changed

+74
-47
lines changed
Lines changed: 74 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,70 +1,97 @@
11
--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
33
--FILE--
44
<?php
55
error_reporting(E_ALL);
66

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);
1117
}
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+
);
1521

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);
1823

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));
2144
}
22-
$writePipes = array($pipes[0]);
23-
$stdinLen = strlen($stdin);
24-
$stdinOffset = 0;
2545

26-
unset($pipes[0]);
46+
fwrite($pipes[0], str_repeat('*', 10000));
47+
fclose($pipes[0]);
2748

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);
3351

34-
if (false === $n) {
35-
break;
36-
} elseif ($n === 0) {
37-
proc_terminate($process);
52+
$buffers = [
53+
1 => "",
54+
2 => ""
55+
];
3856

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);
4866
}
67+
break;
4968
}
5069

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);
5974
}
60-
}
6175

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));
6287

88+
fclose($pipes[1]);
89+
fclose($pipes[2]);
6390
?>
64-
===DONE===
6591
--EXPECTF--
66-
string(2049) "%s"
67-
string(2049) "%s"
92+
string(10000) "%s"
93+
string(10000) "%s"
6894
string(0) ""
6995
string(0) ""
70-
===DONE===
96+
--CLEAN--
97+
unlink($file);

0 commit comments

Comments
 (0)