PipeStdinInStdoutStdErrStreamSelect.php 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  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. die(ERR_SELECT_FAILED);
  27. } elseif ($n < 1) {
  28. die(ERR_TIMEOUT);
  29. }
  30. if (in_array(STDOUT, $w) && strlen($out) > 0) {
  31. $written = fwrite(STDOUT, (string) $out, 32768);
  32. if (false === $written) {
  33. die(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. die(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. die(ERR_READ_FAILED);
  60. }
  61. }
  62. }
  63. }