Updated Drupal to 8.6. This goes with the following updates because it's possible...
[yaffs-website] / vendor / psy / psysh / src / ExecutionLoop / ProcessForker.php
index 1a5bb7a949f152db8182c5a6847ba2fcf341b8a9..4704795942eb583fcaae9c590732681c3a0b89b4 100644 (file)
@@ -33,7 +33,7 @@ class ProcessForker extends AbstractListener
      */
     public static function isSupported()
     {
-        return function_exists('pcntl_signal') && function_exists('posix_getpid');
+        return \function_exists('pcntl_signal') && \function_exists('posix_getpid');
     }
 
     /**
@@ -46,46 +46,61 @@ class ProcessForker extends AbstractListener
      */
     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;
@@ -110,8 +125,8 @@ class ProcessForker extends AbstractListener
     {
         // 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();
         }
     }
 
@@ -125,10 +140,10 @@ class ProcessForker extends AbstractListener
     {
         // 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);
         }
     }
 
@@ -142,18 +157,18 @@ class ProcessForker extends AbstractListener
     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
@@ -184,12 +199,12 @@ class ProcessForker extends AbstractListener
             }
 
             // 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...
@@ -199,6 +214,6 @@ class ProcessForker extends AbstractListener
             }
         }
 
-        return @serialize($serializable);
+        return @\serialize($serializable);
     }
 }