55use Evenement \EventEmitter ;
66use React \EventLoop \LoopInterface ;
77use React \Stream \ReadableResourceStream ;
8+ use React \Stream \ReadableStreamInterface ;
89use React \Stream \WritableResourceStream ;
10+ use React \Stream \WritableStreamInterface ;
911
1012/**
1113 * Process component.
1719 */
1820class Process extends EventEmitter
1921{
22+ /**
23+ * @var ?WritableStreamInterface
24+ */
2025 public $ stdin ;
26+
27+ /**
28+ * @var ?ReadableStreamInterface
29+ */
2130 public $ stdout ;
31+
32+ /**
33+ * @var ?ReadableStreamInterface
34+ */
2235 public $ stderr ;
2336
37+ /**
38+ * Array with all process pipes (once started)
39+ * - 0: STDIN (`WritableStreamInterface`)
40+ * - 1: STDOUT (`ReadableStreamInterface`)
41+ * - 2: STDERR (`ReadableStreamInterface`)
42+ *
43+ * @var ReadableStreamInterface|WritableStreamInterface
44+ */
45+ public $ pipes = array ();
46+
2447 private $ cmd ;
2548 private $ cwd ;
2649 private $ env ;
2750 private $ enhanceSigchildCompatibility ;
28- private $ pipes ;
51+ private $ sigchildPipe ;
2952
3053 private $ process ;
3154 private $ status ;
@@ -90,13 +113,15 @@ public function start(LoopInterface $loop, $interval = 0.1)
90113 array ('pipe ' , 'w ' ), // stderr
91114 );
92115
116+ $ sigchild = null ;
93117 // Read exit code through fourth pipe to work around --enable-sigchild
94118 if ($ this ->enhanceSigchildCompatibility ) {
95119 $ fdSpec [] = array ('pipe ' , 'w ' );
96- $ cmd = sprintf ('(%s) 3>/dev/null; code=$?; echo $code >&3; exit $code ' , $ cmd );
120+ $ sigchild = 3 ;
121+ $ cmd = sprintf ('(%s) ' . $ sigchild . '>/dev/null; code=$?; echo $code >& ' . $ sigchild . '; exit $code ' , $ cmd );
97122 }
98123
99- $ this ->process = proc_open ($ cmd , $ fdSpec , $ this -> pipes , $ this ->cwd , $ this ->env );
124+ $ this ->process = proc_open ($ cmd , $ fdSpec , $ pipes , $ this ->cwd , $ this ->env );
100125
101126 if (!is_resource ($ this ->process )) {
102127 throw new \RuntimeException ('Unable to launch a new process. ' );
@@ -129,11 +154,24 @@ public function start(LoopInterface $loop, $interval = 0.1)
129154 });
130155 };
131156
132- $ this ->stdin = new WritableResourceStream ($ this ->pipes [0 ], $ loop );
133- $ this ->stdout = new ReadableResourceStream ($ this ->pipes [1 ], $ loop );
134- $ this ->stdout ->on ('close ' , $ streamCloseHandler );
135- $ this ->stderr = new ReadableResourceStream ($ this ->pipes [2 ], $ loop );
136- $ this ->stderr ->on ('close ' , $ streamCloseHandler );
157+ if ($ sigchild !== null ) {
158+ $ this ->sigchildPipe = $ pipes [$ sigchild ];
159+ unset($ pipes [$ sigchild ]);
160+ }
161+
162+ foreach ($ pipes as $ n => $ fd ) {
163+ if ($ n === 0 ) {
164+ $ stream = new WritableResourceStream ($ fd , $ loop );
165+ } else {
166+ $ stream = new ReadableResourceStream ($ fd , $ loop );
167+ $ stream ->on ('close ' , $ streamCloseHandler );
168+ }
169+ $ this ->pipes [$ n ] = $ stream ;
170+ }
171+
172+ $ this ->stdin = $ this ->pipes [0 ];
173+ $ this ->stdout = $ this ->pipes [1 ];
174+ $ this ->stderr = $ this ->pipes [2 ];
137175 }
138176
139177 /**
@@ -337,11 +375,11 @@ public final static function setSigchildEnabled($sigchild)
337375 */
338376 private function pollExitCodePipe ()
339377 {
340- if ( ! isset ( $ this ->pipes [ 3 ]) ) {
378+ if ($ this ->sigchildPipe === null ) {
341379 return ;
342380 }
343381
344- $ r = array ($ this ->pipes [ 3 ] );
382+ $ r = array ($ this ->sigchildPipe );
345383 $ w = $ e = null ;
346384
347385 $ n = @stream_select ($ r , $ w , $ e , 0 );
@@ -364,12 +402,12 @@ private function pollExitCodePipe()
364402 */
365403 private function closeExitCodePipe ()
366404 {
367- if ( ! isset ( $ this ->pipes [ 3 ]) ) {
405+ if ($ this ->sigchildPipe === null ) {
368406 return ;
369407 }
370408
371- fclose ($ this ->pipes [ 3 ] );
372- unset( $ this ->pipes [ 3 ]) ;
409+ fclose ($ this ->sigchildPipe );
410+ $ this ->sigchildPipe = null ;
373411 }
374412
375413 /**
0 commit comments