@@ -206,6 +206,9 @@ public function start($callback = null)
206
206
$ this ->fileHandles = array (
207
207
self ::STDOUT => tmpfile (),
208
208
);
209
+ $ this ->readBytes = array (
210
+ self ::STDOUT => 0 ,
211
+ );
209
212
$ descriptors = array (array ('pipe ' , 'r ' ), $ this ->fileHandles [self ::STDOUT ], array ('pipe ' , 'w ' ));
210
213
} else {
211
214
$ descriptors = array (array ('pipe ' , 'r ' ), array ('pipe ' , 'w ' ), array ('pipe ' , 'w ' ));
@@ -236,14 +239,18 @@ public function start($callback = null)
236
239
unset($ this ->pipes [0 ]);
237
240
238
241
return ;
239
- } else {
240
- $ writePipes = array ($ this ->pipes [0 ]);
241
- unset($ this ->pipes [0 ]);
242
- $ stdinLen = strlen ($ this ->stdin );
243
- $ stdinOffset = 0 ;
244
242
}
245
243
244
+ $ writePipes = array ($ this ->pipes [0 ]);
245
+ unset($ this ->pipes [0 ]);
246
+ $ stdinLen = strlen ($ this ->stdin );
247
+ $ stdinOffset = 0 ;
248
+
246
249
while ($ writePipes ) {
250
+ if (defined ('PHP_WINDOWS_VERSION_BUILD ' )) {
251
+ $ this ->processFileHandles ($ callback );
252
+ }
253
+
247
254
$ r = $ this ->pipes ;
248
255
$ w = $ writePipes ;
249
256
$ e = null ;
@@ -252,7 +259,8 @@ public function start($callback = null)
252
259
253
260
if (false === $ n ) {
254
261
break ;
255
- } elseif ($ n === 0 ) {
262
+ }
263
+ if ($ n === 0 ) {
256
264
proc_terminate ($ this ->process );
257
265
258
266
throw new \RuntimeException ('The process timed out. ' );
@@ -269,22 +277,6 @@ public function start($callback = null)
269
277
}
270
278
}
271
279
272
- if (defined ('PHP_WINDOWS_VERSION_BUILD ' )) {
273
- $ fh = $ this ->fileHandles ;
274
- foreach ($ fh as $ type => $ fileHandle ) {
275
- fseek ($ fileHandle , 0 );
276
- $ data = fread ($ fileHandle , 8192 );
277
- $ this ->readBytes [$ type ] = strlen ($ data );
278
- if (strlen ($ data ) > 0 ) {
279
- call_user_func ($ callback , $ type == 1 ? self ::OUT : self ::ERR , $ data );
280
- }
281
- if (false === $ data ) {
282
- fclose ($ fileHandle );
283
- unset($ this ->fileHandles [$ type ]);
284
- }
285
- }
286
- }
287
-
288
280
foreach ($ r as $ pipe ) {
289
281
$ type = array_search ($ pipe , $ this ->pipes );
290
282
$ data = fread ($ pipe , 8192 );
@@ -319,53 +311,40 @@ public function wait($callback = null)
319
311
$ this ->processInformation = proc_get_status ($ this ->process );
320
312
$ callback = $ this ->buildCallback ($ callback );
321
313
while ($ this ->pipes || (defined ('PHP_WINDOWS_VERSION_BUILD ' ) && $ this ->fileHandles )) {
322
- $ r = $ this ->pipes ;
323
- $ w = null ;
324
- $ e = null ;
314
+ if ( defined ( ' PHP_WINDOWS_VERSION_BUILD ' ) && $ this ->fileHandles ) {
315
+ $ this -> processFileHandles ( $ callback , ! $ this -> pipes ) ;
316
+ }
325
317
326
- $ n = @stream_select ($ r , $ w , $ e , $ this ->timeout );
318
+ if ($ this ->pipes ) {
319
+ $ r = $ this ->pipes ;
320
+ $ w = null ;
321
+ $ e = null ;
327
322
328
- if (false === $ n ) {
329
- break ;
330
- }
331
- if (0 === $ n ) {
332
- proc_terminate ($ this ->process );
323
+ $ n = @stream_select ($ r , $ w , $ e , $ this ->timeout );
333
324
334
- throw new \ RuntimeException ( ' The process timed out. ' );
335
- }
325
+ if ( false === $ n ) {
326
+ $ this -> pipes = array ();
336
327
337
- if (defined ('PHP_WINDOWS_VERSION_BUILD ' )) {
338
- $ fh = $ this ->fileHandles ;
339
- foreach ($ fh as $ type => $ fileHandle ) {
340
- fseek ($ fileHandle , $ this ->readBytes [$ type ]);
341
- $ data = fread ($ fileHandle , 8192 );
342
- if (isset ($ this ->readBytes )) {
343
- $ this ->readBytes [$ type ] += strlen ($ data );
344
- } else {
345
- $ this ->readBytes [$ type ] = strlen ($ data );
346
- }
328
+ continue ;
329
+ }
330
+ if (0 === $ n ) {
331
+ proc_terminate ($ this ->process );
347
332
333
+ throw new \RuntimeException ('The process timed out. ' );
334
+ }
335
+
336
+ foreach ($ r as $ pipe ) {
337
+ $ type = array_search ($ pipe , $ this ->pipes );
338
+ $ data = fread ($ pipe , 8192 );
348
339
if (strlen ($ data ) > 0 ) {
349
340
call_user_func ($ callback , $ type == 1 ? self ::OUT : self ::ERR , $ data );
350
341
}
351
- if (false === $ data ) {
352
- fclose ($ fileHandle );
353
- unset($ this ->fileHandles [$ type ]);
342
+ if (false === $ data || feof ( $ pipe ) ) {
343
+ fclose ($ pipe );
344
+ unset($ this ->pipes [$ type ]);
354
345
}
355
346
}
356
347
}
357
-
358
- foreach ($ r as $ pipe ) {
359
- $ type = array_search ($ pipe , $ this ->pipes );
360
- $ data = fread ($ pipe , 8192 );
361
- if (strlen ($ data ) > 0 ) {
362
- call_user_func ($ callback , $ type == 1 ? self ::OUT : self ::ERR , $ data );
363
- }
364
- if (false === $ data || feof ($ pipe )) {
365
- fclose ($ pipe );
366
- unset($ this ->pipes [$ type ]);
367
- }
368
- }
369
348
}
370
349
$ this ->updateStatus ();
371
350
if ($ this ->processInformation ['signaled ' ]) {
@@ -725,4 +704,27 @@ protected function updateOutput()
725
704
$ this ->addOutput (stream_get_contents ($ this ->pipes [self ::STDOUT ]));
726
705
}
727
706
}
707
+
708
+ /**
709
+ * Handles the windows file handles fallbacks
710
+ *
711
+ * @param mixed $callback A valid PHP callback
712
+ * @param Boolean $closeEmptyHandles if true, handles that are empty will be assumed closed
713
+ */
714
+ private function processFileHandles ($ callback , $ closeEmptyHandles = false )
715
+ {
716
+ $ fh = $ this ->fileHandles ;
717
+ foreach ($ fh as $ type => $ fileHandle ) {
718
+ fseek ($ fileHandle , $ this ->readBytes [$ type ]);
719
+ $ data = fread ($ fileHandle , 8192 );
720
+ if (strlen ($ data ) > 0 ) {
721
+ $ this ->readBytes [$ type ] += strlen ($ data );
722
+ call_user_func ($ callback , $ type == 1 ? self ::OUT : self ::ERR , $ data );
723
+ }
724
+ if (false === $ data || ($ closeEmptyHandles && '' === $ data && feof ($ fileHandle ))) {
725
+ fclose ($ fileHandle );
726
+ unset($ this ->fileHandles [$ type ]);
727
+ }
728
+ }
729
+ }
728
730
}
0 commit comments