public function beforeRun(Shell $shell)
    {
        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();
        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);

            // Wait for a return value from the loop process.
            $read   = [$down];
            $write  = null;
            $except = null;

            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));
            }

            throw new BreakException('Exiting main thread');
        }

        // This is the child process. It's going to do all the work.
        if (\function_exists('setproctitle')) {
            setproctitle('psysh (loop)');
        }

        // We won't be needing this one.
        \fclose($down);

        // Save this; we'll need to close it in `afterRun`
        $this->up = $up;
    }
public function beforeRun(Shell $shell)
    {
        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();
        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);

            // Wait for a return value from the loop process.
            $read   = [$down];
            $write  = null;
            $except = null;

            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));
            }

            throw new BreakException('Exiting main thread');
        }

        // This is the child process. It's going to do all the work.
        if (\function_exists('setproctitle')) {
            setproctitle('psysh (loop)');
        }

        // We won't be needing this one.
        \fclose($down);

        // Save this; we'll need to close it in `afterRun`
        $this->up = $up;
    }
public function beforeRun ( Shell $ shell ) { 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 ( ) ; 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 ) ; // Wait for a return value from the loop process. $ read = [ $ down ] ; $ write = null ; $ except = null ; 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 ) ) ; } throw new BreakException ( 'Exiting main thread' ) ; } // This is the child process. It's going to do all the work. if ( \ function_exists ( 'setproctitle' ) ) { setproctitle ( 'psysh (loop)' ) ; } // We won't be needing this one. \ fclose ( $ down ) ; // Save this; we'll need to close it in `afterRun` $ this -> up = $ up ; }
Forks into a master and a loop process.

The loop process will handle the evaluation of all instructions, then
return its state via a socket upon completion.

@param Shell $shell
Forks into a master and a loop process .