@@ -76,12 +76,12 @@ class Process
76
76
77
77
private static $ sigchild ;
78
78
private static $ posixSignals = array (
79
- 1 => 1 , // SIGHUP
80
- 2 => 2 , // SIGINT
81
- 3 => 3 , // SIGQUIT
82
- 6 => 6 , // SIGABRT
83
- 14 => 14 , // SIGALRM
84
- 15 => 15 , // SIGTERM
79
+ 1 , // SIGHUP
80
+ 2 , // SIGINT
81
+ 3 , // SIGQUIT
82
+ 6 , // SIGABRT
83
+ 14 , // SIGALRM
84
+ 15 , // SIGTERM
85
85
);
86
86
87
87
/**
@@ -285,27 +285,34 @@ public function start($callback = null)
285
285
if (!isset ($ this ->options ['bypass_shell ' ])) {
286
286
$ this ->options ['bypass_shell ' ] = true ;
287
287
}
288
- }
288
+ } elseif (!$ this ->useFileHandles && $ this ->enhanceSigchildCompatibility && $ this ->isSigchildEnabled ()) {
289
+ // last exit code is output on the fourth pipe and caught to work around --enable-sigchild
290
+ $ descriptors [3 ] = array ('pipe ' , 'w ' );
291
+
292
+ $ commandline = '' ;
293
+ foreach (self ::$ posixSignals as $ s ) {
294
+ $ commandline .= "trap 'echo s $ s >&3' $ s; " ;
295
+ }
289
296
290
- $ ptsWorkaround = null ;
297
+ $ commandline .= '{ ( ' .$ this ->commandline .') <&3 3<&- 3>/dev/null & } 3<&0; ' ;
298
+ $ commandline .= 'pid=$!; echo $pid >&3; wait $pid; code=$?; echo x$code >&3; exit $code ' ;
291
299
292
- if (!$ this ->useFileHandles && $ this ->enhanceSigchildCompatibility && $ this ->isSigchildEnabled ()) {
293
300
// Workaround for the bug, when PTS functionality is enabled.
294
301
// @see : https://bugs.php.net/69442
295
302
$ ptsWorkaround = fopen (__FILE__ , 'r ' );
296
303
}
297
304
298
305
$ this ->process = proc_open ($ commandline , $ descriptors , $ this ->processPipes ->pipes , $ this ->cwd , $ this ->env , $ this ->options );
299
306
300
- if ($ ptsWorkaround ) {
301
- fclose ($ ptsWorkaround );
302
- }
303
-
304
307
if (!is_resource ($ this ->process )) {
305
308
throw new RuntimeException ('Unable to launch a new process. ' );
306
309
}
307
310
$ this ->status = self ::STATUS_STARTED ;
308
311
312
+ if (isset ($ descriptors [3 ])) {
313
+ fclose ($ ptsWorkaround );
314
+ $ this ->fallbackStatus ['pid ' ] = (int ) fgets ($ this ->processPipes ->pipes [3 ]);
315
+ }
309
316
if ($ this ->tty ) {
310
317
return ;
311
318
}
@@ -422,6 +429,8 @@ public function signal($signal)
422
429
public function disableOutput ()
423
430
{
424
431
if ($ this ->isRunning ()) {
432
+ $ this ->stop (0 );
433
+
425
434
throw new RuntimeException ('Disabling output while the process is running is not possible. ' );
426
435
}
427
436
if (null !== $ this ->idleTimeout ) {
@@ -443,6 +452,8 @@ public function disableOutput()
443
452
public function enableOutput ()
444
453
{
445
454
if ($ this ->isRunning ()) {
455
+ $ this ->stop (0 );
456
+
446
457
throw new RuntimeException ('Enabling output while the process is running is not possible. ' );
447
458
}
448
459
@@ -472,6 +483,8 @@ public function isOutputDisabled()
472
483
public function getOutput ()
473
484
{
474
485
if ($ this ->outputDisabled ) {
486
+ $ this ->stop (0 );
487
+
475
488
throw new LogicException ('Output has been disabled. ' );
476
489
}
477
490
@@ -1245,22 +1258,8 @@ private function getDescriptors()
1245
1258
} else {
1246
1259
$ this ->processPipes = UnixPipes::create ($ this , $ this ->input );
1247
1260
}
1248
- $ descriptors = $ this ->processPipes ->getDescriptors ($ this ->outputDisabled );
1249
-
1250
- if (!$ this ->useFileHandles && $ this ->enhanceSigchildCompatibility && $ this ->isSigchildEnabled ()) {
1251
- // last exit code is output on the fourth pipe and caught to work around --enable-sigchild
1252
- $ descriptors [3 ] = array ('pipe ' , 'w ' );
1253
-
1254
- $ trap = '' ;
1255
- foreach (self ::$ posixSignals as $ s ) {
1256
- $ trap .= "trap 'echo s $ s >&3' $ s; " ;
1257
- }
1258
-
1259
- $ this ->commandline = $ trap .'{ ( ' .$ this ->commandline .') <&3 3<&- 3>/dev/null & } 3<&0; ' ;
1260
- $ this ->commandline .= 'pid=$!; echo p$pid >&3; wait $pid; code=$?; echo x$code >&3; exit $code ' ;
1261
- }
1262
1261
1263
- return $ descriptors ;
1262
+ return $ this -> processPipes -> getDescriptors ( $ this -> outputDisabled ) ;
1264
1263
}
1265
1264
1266
1265
/**
@@ -1462,14 +1461,6 @@ private function doSignal($signal, $throwException)
1462
1461
return false ;
1463
1462
}
1464
1463
1465
- if ($ this ->enhanceSigchildCompatibility && $ this ->isSigchildEnabled () && !isset (self ::$ posixSignals [$ signal ]) && !(function_exists ('posix_kill ' ) && @posix_kill ($ this ->getPid (), $ signal ))) {
1466
- if ($ throwException ) {
1467
- throw new RuntimeException ('This PHP has been compiled with --enable-sigchild and posix_kill() is not available. ' );
1468
- }
1469
-
1470
- return false ;
1471
- }
1472
-
1473
1464
if ('\\' === DIRECTORY_SEPARATOR ) {
1474
1465
exec (sprintf ('taskkill /F /T /PID %d 2>&1 ' , $ this ->getPid ()), $ output , $ exitCode );
1475
1466
if ($ exitCode && $ this ->isRunning ()) {
@@ -1479,14 +1470,21 @@ private function doSignal($signal, $throwException)
1479
1470
1480
1471
return false ;
1481
1472
}
1482
- }
1483
-
1484
- if (true !== @proc_terminate ($ this ->process , $ signal ) && '\\' !== DIRECTORY_SEPARATOR ) {
1485
- if ($ throwException ) {
1486
- throw new RuntimeException (sprintf ('Error while sending signal `%s`. ' , $ signal ));
1473
+ } else {
1474
+ if (!$ this ->enhanceSigchildCompatibility || !$ this ->isSigchildEnabled ()) {
1475
+ $ ok = @proc_terminate ($ this ->process , $ signal );
1476
+ } elseif (function_exists ('posix_kill ' )) {
1477
+ $ ok = @posix_kill ($ this ->getPid (), $ signal );
1478
+ } elseif ($ ok = proc_open (sprintf ('kill -%d %d ' , $ signal , $ this ->getPid ()), array (2 => array ('pipe ' , 'w ' )), $ pipes )) {
1479
+ $ ok = false === fgets ($ pipes [2 ]);
1487
1480
}
1481
+ if (!$ ok ) {
1482
+ if ($ throwException ) {
1483
+ throw new RuntimeException (sprintf ('Error while sending signal `%s`. ' , $ signal ));
1484
+ }
1488
1485
1489
- return false ;
1486
+ return false ;
1487
+ }
1490
1488
}
1491
1489
1492
1490
$ this ->latestSignal = (int ) $ signal ;
0 commit comments