/** * Starts the process and returns after sending the STDIN. * * This method blocks until all STDIN data is sent to the process then it * returns while the process runs in the background. * * The termination of the process can be awaited with wait(). * * The callback receives the type of output (out or err) and some bytes from * the output in real-time while writing the standard input to the process. * It allows to have feedback from the independent process during execution. * If there is no callback passed, the wait() method can be called * with true as a second parameter then the callback will get all data occurred * in (and since) the start call. * * @param callback|null $callback A PHP callback to run whenever there is some * output available on STDOUT or STDERR * * @throws RuntimeException When process can't be launched * @throws RuntimeException When process is already running */ public function start($callback = null) { if ($this->isRunning()) { throw new RuntimeException('Process is already running'); } $this->resetProcessData(); $this->starttime = microtime(true); $this->callback = $this->buildCallback($callback); $descriptors = $this->getDescriptors(); $commandline = $this->commandline; if ('\\' === DIRECTORY_SEPARATOR && $this->enhanceWindowsCompatibility) { $commandline = 'cmd /V:ON /E:ON /D /C "(' . $commandline . ')'; foreach ($this->processPipes->getFiles() as $offset => $filename) { $commandline .= ' ' . $offset . '>' . ProcessUtils::escapeArgument($filename); } $commandline .= '"'; if (!isset($this->options['bypass_shell'])) { $this->options['bypass_shell'] = true; } } $this->process = proc_open($commandline, $descriptors, $this->processPipes->pipes, $this->cwd, $this->env, $this->options); if (!is_resource($this->process)) { throw new RuntimeException('Unable to launch a new process.'); } $this->status = self::STATUS_STARTED; $this->processPipes->unblock(); if ($this->tty) { return; } $this->processPipes->write(false, $this->stdin); $this->updateStatus(false); $this->checkTimeout(); }
/** * Starts the process and returns after sending the STDIN. * * This method blocks until all STDIN data is sent to the process then it * returns while the process runs in the background. * * The termination of the process can be awaited with wait(). * * The callback receives the type of output (out or err) and some bytes from * the output in real-time while writing the standard input to the process. * It allows to have feedback from the independent process during execution. * If there is no callback passed, the wait() method can be called * with true as a second parameter then the callback will get all data occurred * in (and since) the start call. * * @param callback|null $callback A PHP callback to run whenever there is some * output available on STDOUT or STDERR * * @throws RuntimeException When process can't be launch or is stopped * @throws RuntimeException When process is already running */ public function start($callback = null) { if ($this->isRunning()) { throw new RuntimeException('Process is already running'); } $this->resetProcessData(); $this->starttime = microtime(true); $this->callback = $this->buildCallback($callback); $descriptors = $this->getDescriptors(); $commandline = $this->commandline; if (defined('PHP_WINDOWS_VERSION_BUILD') && $this->enhanceWindowsCompatibility) { $commandline = 'cmd /V:ON /E:ON /C "' . $commandline . '"'; if (!isset($this->options['bypass_shell'])) { $this->options['bypass_shell'] = true; } } $this->process = proc_open($commandline, $descriptors, $this->processPipes->pipes, $this->cwd, $this->env, $this->options); if (!is_resource($this->process)) { throw new RuntimeException('Unable to launch a new process.'); } $this->status = self::STATUS_STARTED; $this->processPipes->unblock(); if ($this->tty) { $this->status = self::STATUS_TERMINATED; return; } $this->processPipes->write(false, $this->stdin); $this->updateStatus(false); $this->checkTimeout(); }
/** * Starts the process and returns after sending the STDIN. * * This method blocks until all STDIN data is sent to the process then it * returns while the process runs in the background. * * The termination of the process can be awaited with wait(). * * The callback receives the type of output (out or err) and some bytes from * the output in real-time while writing the standard input to the process. * It allows to have feedback from the independent process during execution. * If there is no callback passed, the wait() method can be called * with true as a second parameter then the callback will get all data occurred * in (and since) the start call. * * @param callback|null $callback A PHP callback to run whenever there is some * output available on STDOUT or STDERR * * @throws RuntimeException When process can't be launch or is stopped * @throws RuntimeException When process is already running */ public function start($callback = null) { if ($this->isRunning()) { throw new RuntimeException('Process is already running'); } $this->resetProcessData(); $this->starttime = microtime(true); $this->callback = $this->buildCallback($callback); $this->processPipes = new ProcessPipes($this->useFileHandles); $descriptors = $this->processPipes->getDescriptors(); if (!$this->useFileHandles && $this->enhanceSigchildCompatibility && $this->isSigchildEnabled()) { // last exit code is output on the fourth pipe and caught to work around --enable-sigchild $descriptors = array_merge($descriptors, array(array('pipe', 'w'))); $this->commandline = '(' . $this->commandline . ') 3>/dev/null; code=$?; echo $code >&3; exit $code'; } $commandline = $this->commandline; if (defined('PHP_WINDOWS_VERSION_BUILD') && $this->enhanceWindowsCompatibility) { $commandline = 'cmd /V:ON /E:ON /C "' . $commandline . '"'; if (!isset($this->options['bypass_shell'])) { $this->options['bypass_shell'] = true; } } $this->process = proc_open($commandline, $descriptors, $this->processPipes->pipes, $this->cwd, $this->env, $this->options); if (!is_resource($this->process)) { throw new RuntimeException('Unable to launch a new process.'); } $this->status = self::STATUS_STARTED; $this->processPipes->unblock(); $this->processPipes->write(false, $this->stdin); $this->updateStatus(false); $this->checkTimeout(); }
/** * Starts the process and returns after sending the STDIN. * * This method blocks until all STDIN data is sent to the process then it * returns while the process runs in the background. * * The termination of the process can be awaited with wait(). * * The callback receives the type of output (out or err) and some bytes from * the output in real-time while writing the standard input to the process. * It allows to have feedback from the independent process during execution. * If there is no callback passed, the wait() method can be called * with true as a second parameter then the callback will get all data occurred * in (and since) the start call. * * @param callback|null $callback A PHP callback to run whenever there is some * output available on STDOUT or STDERR * * @throws RuntimeException When process can't be launched * @throws RuntimeException When process is already running */ public function start($callback = null) { if ($this->isRunning()) { throw new RuntimeException('Process is already running'); } $this->resetProcessData(); $this->starttime = microtime(true); $this->callback = $this->buildCallback($callback); $descriptors = $this->getDescriptors(); $commandline = $this->commandline; if ('\\' === DIRECTORY_SEPARATOR && $this->enhanceWindowsCompatibility) { $commandline = 'cmd /V:ON /E:ON /D /C "(' . $commandline . ')'; foreach ($this->processPipes->getFiles() as $offset => $filename) { $commandline .= ' ' . $offset . '>' . ProcessUtils::escapeArgument($filename); } $commandline .= '"'; if (!isset($this->options['bypass_shell'])) { $this->options['bypass_shell'] = true; } } elseif (!$this->useFileHandles && $this->enhanceSigchildCompatibility && $this->isSigchildEnabled()) { // last exit code is output on the fourth pipe and caught to work around --enable-sigchild $descriptors[3] = array('pipe', 'w'); // See https://unix.stackexchange.com/questions/71205/background-process-pipe-input $commandline = '{ (' . $this->commandline . ') <&3 3<&- 3>/dev/null & } 3<&0;'; $commandline .= 'pid=$!; echo $pid >&3; wait $pid; code=$?; echo $code >&3; exit $code'; // Workaround for the bug, when PTS functionality is enabled. // @see : https://bugs.php.net/69442 $ptsWorkaround = fopen(__FILE__, 'r'); } $this->process = proc_open($commandline, $descriptors, $this->processPipes->pipes, $this->cwd, $this->env, $this->options); if (!is_resource($this->process)) { throw new RuntimeException('Unable to launch a new process.'); } $this->status = self::STATUS_STARTED; if (isset($descriptors[3])) { $this->fallbackStatus['pid'] = (int) fgets($this->processPipes->pipes[3]); } $this->processPipes->unblock(); if ($this->tty) { return; } $this->processPipes->write(false, $this->stdin); $this->updateStatus(false); $this->checkTimeout(); }
/** * Starts the process and returns after sending the STDIN. * * This method blocks until all STDIN data is sent to the process then it * returns while the process runs in the background. * * The termination of the process can be awaited with wait(). * * The callback receives the type of output (out or err) and some bytes from * the output in real-time while writing the standard input to the process. * It allows to have feedback from the independent process during execution. * If there is no callback passed, the wait() method can be called * with true as a second parameter then the callback will get all data occurred * in (and since) the start call. * * @param callback|null $callback A PHP callback to run whenever there is some * output available on STDOUT or STDERR * * @throws RuntimeException When process can't be launched * @throws RuntimeException When process is already running */ public function start($callback = null) { if ($this->isRunning()) { throw new RuntimeException('Process is already running'); } $this->resetProcessData(); $this->starttime = microtime(true); $this->callback = $this->buildCallback($callback); $descriptors = $this->getDescriptors(); $commandline = $this->commandline; if ('\\' === DIRECTORY_SEPARATOR && $this->enhanceWindowsCompatibility) { $commandline = 'cmd /V:ON /E:ON /D /C "(' . $commandline . ')'; foreach ($this->processPipes->getFiles() as $offset => $filename) { $commandline .= ' ' . $offset . '>' . ProcessUtils::escapeArgument($filename); } $commandline .= '"'; if (!isset($this->options['bypass_shell'])) { $this->options['bypass_shell'] = true; } } $ptsWorkaround = null; if (!$this->useFileHandles && $this->enhanceSigchildCompatibility && $this->isSigchildEnabled()) { // Workaround for the bug, when PTS functionality is enabled. // @see : https://bugs.php.net/69442 $ptsWorkaround = fopen(__FILE__, 'r'); } $this->process = proc_open($commandline, $descriptors, $this->processPipes->pipes, $this->cwd, $this->env, $this->options); if ($ptsWorkaround) { fclose($ptsWorkaround); } if (!is_resource($this->process)) { throw new RuntimeException('Unable to launch a new process.'); } $this->status = self::STATUS_STARTED; $this->processPipes->unblock(); if ($this->tty) { return; } $this->processPipes->write(false, $this->stdin); $this->updateStatus(false); $this->checkTimeout(); }
/** * Starts the process and returns after writing the input to STDIN. * * This method blocks until all STDIN data is sent to the process then it * returns while the process runs in the background. * * The termination of the process can be awaited with wait(). * * The callback receives the type of output (out or err) and some bytes from * the output in real-time while writing the standard input to the process. * It allows to have feedback from the independent process during execution. * If there is no callback passed, the wait() method can be called * with true as a second parameter then the callback will get all data occurred * in (and since) the start call. * * @param callable|null $callback A PHP callback to run whenever there is some * output available on STDOUT or STDERR * * @return Process The process itself * * @throws RuntimeException When process can't be launched * @throws RuntimeException When process is already running * @throws LogicException In case a callback is provided and output has been disabled */ public function start($callback = null) { if ($this->isRunning()) { throw new RuntimeException('Process is already running'); } if ($this->outputDisabled && null !== $callback) { throw new LogicException('Output has been disabled, enable it to allow the use of a callback.'); } $this->resetProcessData(); $this->starttime = $this->lastOutputTime = microtime(true); $this->callback = $this->buildCallback($callback); $descriptors = $this->getDescriptors(); $commandline = $this->commandline; if (defined('PHP_WINDOWS_VERSION_BUILD') && $this->enhanceWindowsCompatibility) { $commandline = 'cmd /V:ON /E:ON /C "(' . $commandline . ')'; foreach ($this->processPipes->getFiles() as $offset => $filename) { $commandline .= ' ' . $offset . '>' . ProcessUtils::escapeArgument($filename); } $commandline .= '"'; if (!isset($this->options['bypass_shell'])) { $this->options['bypass_shell'] = true; } } $this->process = proc_open($commandline, $descriptors, $this->processPipes->pipes, $this->cwd, $this->env, $this->options); if (!is_resource($this->process)) { throw new RuntimeException('Unable to launch a new process.'); } $this->status = self::STATUS_STARTED; $this->processPipes->unblock(); if ($this->tty) { return; } $this->processPipes->write(false, $this->input); $this->updateStatus(false); $this->checkTimeout(); }