*/
public static function isSupported()
{
- return function_exists('pcntl_signal') && function_exists('posix_getpid');
+ return \function_exists('pcntl_signal') && \function_exists('posix_getpid');
}
/**
*/
public function beforeRun(Shell $shell)
{
- list($up, $down) = stream_socket_pair(STREAM_PF_UNIX, STREAM_SOCK_STREAM, STREAM_IPPROTO_IP);
+ list($up, $down) = \stream_socket_pair(STREAM_PF_UNIX, STREAM_SOCK_STREAM, STREAM_IPPROTO_IP);
if (!$up) {
throw new \RuntimeException('Unable to create socket pair');
}
- $pid = pcntl_fork();
+ $pid = \pcntl_fork();
if ($pid < 0) {
throw new \RuntimeException('Unable to start execution loop');
} elseif ($pid > 0) {
// This is the main thread. We'll just wait for a while.
// We won't be needing this one.
- fclose($up);
+ \fclose($up);
// Wait for a return value from the loop process.
$read = [$down];
$write = null;
$except = null;
- if (stream_select($read, $write, $except, null) === false) {
- throw new \RuntimeException('Error waiting for execution loop');
- }
- $content = stream_get_contents($down);
- fclose($down);
+ do {
+ $n = @\stream_select($read, $write, $except, null);
+
+ if ($n === 0) {
+ throw new \RuntimeException('Process timed out waiting for execution loop');
+ }
+
+ if ($n === false) {
+ $err = \error_get_last();
+ if (!isset($err['message']) || \stripos($err['message'], 'interrupted system call') === false) {
+ $msg = $err['message'] ?
+ \sprintf('Error waiting for execution loop: %s', $err['message']) :
+ 'Error waiting for execution loop';
+ throw new \RuntimeException($msg);
+ }
+ }
+ } while ($n < 1);
+
+ $content = \stream_get_contents($down);
+ \fclose($down);
if ($content) {
- $shell->setScopeVariables(@unserialize($content));
+ $shell->setScopeVariables(@\unserialize($content));
}
throw new BreakException('Exiting main thread');
}
// This is the child process. It's going to do all the work.
- if (function_exists('setproctitle')) {
+ if (\function_exists('setproctitle')) {
setproctitle('psysh (loop)');
}
// We won't be needing this one.
- fclose($down);
+ \fclose($down);
// Save this; we'll need to close it in `afterRun`
$this->up = $up;
{
// if there's an old savegame hanging around, let's kill it.
if (isset($this->savegame)) {
- posix_kill($this->savegame, SIGKILL);
- pcntl_signal_dispatch();
+ \posix_kill($this->savegame, SIGKILL);
+ \pcntl_signal_dispatch();
}
}
{
// We're a child thread. Send the scope variables back up to the main thread.
if (isset($this->up)) {
- fwrite($this->up, $this->serializeReturn($shell->getScopeVariables(false)));
- fclose($this->up);
+ \fwrite($this->up, $this->serializeReturn($shell->getScopeVariables(false)));
+ \fclose($this->up);
- posix_kill(posix_getpid(), SIGKILL);
+ \posix_kill(\posix_getpid(), SIGKILL);
}
}
private function createSavegame()
{
// the current process will become the savegame
- $this->savegame = posix_getpid();
+ $this->savegame = \posix_getpid();
- $pid = pcntl_fork();
+ $pid = \pcntl_fork();
if ($pid < 0) {
throw new \RuntimeException('Unable to create savegame fork');
} elseif ($pid > 0) {
// we're the savegame now... let's wait and see what happens
- pcntl_waitpid($pid, $status);
+ \pcntl_waitpid($pid, $status);
// worker exited cleanly, let's bail
- if (!pcntl_wexitstatus($status)) {
- posix_kill(posix_getpid(), SIGKILL);
+ if (!\pcntl_wexitstatus($status)) {
+ \posix_kill(\posix_getpid(), SIGKILL);
}
// worker didn't exit cleanly, we'll need to have another go
}
// Resources and Closures don't error, but they don't serialize well either.
- if (is_resource($value) || $value instanceof \Closure) {
+ if (\is_resource($value) || $value instanceof \Closure) {
continue;
}
try {
- @serialize($value);
+ @\serialize($value);
$serializable[$key] = $value;
} catch (\Throwable $e) {
// we'll just ignore this one...
}
}
- return @serialize($serializable);
+ return @\serialize($serializable);
}
}