PipeStdinInStdoutStdErrStreamSelect.php 1.7 KB

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