start(Loop::get()); if ($process->stdin !== null) { $process->stdin->end(); } if ($process->stdout) { $process->stdout->on('data', function ($chunk) use (&$bufferOut) { $bufferOut .= (string)$chunk; }); } if ($process->stderr) { $process->stderr->on('data', function ($chunk) use (&$bufferErr) { $bufferErr .= (string)$chunk; }); } if ($timeoutSecs !== null && $timeoutSecs > 0) { $timers['timeout'] = Loop::addTimer($timeoutSecs, function () use ($process, $deferred) { if ($process->isRunning()) { $process->terminate(); // SIGTERM Loop::addTimer(1.0, function () use ($process) { if ($process->isRunning()) { $process->terminate(\defined('SIGKILL') ? \SIGKILL : null); } }); } $deferred->reject(new \RuntimeException('CLI timeout')); }); } $process->on('exit', function ($exitCode) use (&$bufferOut, &$bufferErr, $deferred, &$timers) { foreach ($timers as $t) { if ($t) { Loop::cancelTimer($t); } } $output = trim($bufferOut !== '' ? $bufferOut : $bufferErr); $deferred->resolve([(int)$exitCode, $output]); }); $process->on('error', function (\Throwable $e) use ($deferred, &$timers) { foreach ($timers as $t) { if ($t) { Loop::cancelTimer($t); } } $deferred->reject($e); }); return $deferred->promise(); } }