1<?php
2
3/*
4 * This file is part of the Symfony package.
5 *
6 * (c) Fabien Potencier <fabien@symfony.com>
7 *
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
10 */
11
12define('ERR_SELECT_FAILED', 1);
13define('ERR_TIMEOUT', 2);
14define('ERR_READ_FAILED', 3);
15define('ERR_WRITE_FAILED', 4);
16
17$read = [\STDIN];
18$write = [\STDOUT, \STDERR];
19
20stream_set_blocking(\STDIN, 0);
21stream_set_blocking(\STDOUT, 0);
22stream_set_blocking(\STDERR, 0);
23
24$out = $err = '';
25while ($read || $write) {
26    $r = $read;
27    $w = $write;
28    $e = null;
29    $n = stream_select($r, $w, $e, 5);
30
31    if (false === $n) {
32        exit(ERR_SELECT_FAILED);
33    } elseif ($n < 1) {
34        exit(ERR_TIMEOUT);
35    }
36
37    if (in_array(\STDOUT, $w) && strlen($out) > 0) {
38        $written = fwrite(\STDOUT, (string) $out, 32768);
39        if (false === $written) {
40            exit(ERR_WRITE_FAILED);
41        }
42        $out = (string) substr($out, $written);
43    }
44    if (null === $read && '' === $out) {
45        $write = array_diff($write, [\STDOUT]);
46    }
47
48    if (in_array(\STDERR, $w) && strlen($err) > 0) {
49        $written = fwrite(\STDERR, (string) $err, 32768);
50        if (false === $written) {
51            exit(ERR_WRITE_FAILED);
52        }
53        $err = (string) substr($err, $written);
54    }
55    if (null === $read && '' === $err) {
56        $write = array_diff($write, [\STDERR]);
57    }
58
59    if ($r) {
60        $str = fread(\STDIN, 32768);
61        if (false !== $str) {
62            $out .= $str;
63            $err .= $str;
64        }
65        if (false === $str || feof(\STDIN)) {
66            $read = null;
67            if (!feof(\STDIN)) {
68                exit(ERR_READ_FAILED);
69            }
70        }
71    }
72}
73