Changeset View
Changeset View
Standalone View
Standalone View
src/future/exec/ExecFuture.php
Show First 20 Lines • Show All 186 Lines • ▼ Show 20 Lines | /* -( Interacting With Commands )------------------------------------------ */ | ||||
* NOTE: If you call @{method:discardBuffers}, all the stdout/stderr data | * NOTE: If you call @{method:discardBuffers}, all the stdout/stderr data | ||||
* will be thrown away and the cursors will be reset. | * will be thrown away and the cursors will be reset. | ||||
* | * | ||||
* @return pair <$stdout, $stderr> pair with new output since the last call | * @return pair <$stdout, $stderr> pair with new output since the last call | ||||
* to this method. | * to this method. | ||||
* @task interact | * @task interact | ||||
*/ | */ | ||||
public function read() { | public function read() { | ||||
$stdout = $this->readStdout(); | $stdout_value = $this->readStdout(); | ||||
$stderr = $this->stderr; | |||||
if ($stderr === null) { | |||||
$stderr_value = ''; | |||||
} else { | |||||
$stderr_value = substr($stderr, $this->stderrPos); | |||||
} | |||||
$result = array( | $result = array( | ||||
$stdout, | $stdout_value, | ||||
(string)substr($this->stderr, $this->stderrPos), | $stderr_value, | ||||
); | ); | ||||
$this->stderrPos = strlen($this->stderr); | $this->stderrPos = $this->getStderrBufferLength(); | ||||
return $result; | return $result; | ||||
} | } | ||||
public function readStdout() { | public function readStdout() { | ||||
if ($this->start) { | if ($this->start) { | ||||
$this->updateFuture(); // Sync | $this->updateFuture(); // Sync | ||||
} | } | ||||
$result = (string)substr($this->stdout, $this->stdoutPos); | $stdout = $this->stdout; | ||||
$this->stdoutPos = strlen($this->stdout); | |||||
if ($stdout === null) { | |||||
$result = ''; | |||||
} else { | |||||
$result = substr($stdout, $this->stdoutPos); | |||||
} | |||||
$this->stdoutPos = $this->getStdoutBufferLength(); | |||||
return $result; | return $result; | ||||
} | } | ||||
/** | /** | ||||
* Write data to stdin of the command. | * Write data to stdin of the command. | ||||
* | * | ||||
* @param string Data to write. | * @param string Data to write. | ||||
▲ Show 20 Lines • Show All 248 Lines • ▼ Show 20 Lines | /* -( Internals )---------------------------------------------------------- */ | ||||
/** | /** | ||||
* Determine if the read buffer is empty. | * Determine if the read buffer is empty. | ||||
* | * | ||||
* @return bool True if the read buffer is empty. | * @return bool True if the read buffer is empty. | ||||
* @task internal | * @task internal | ||||
*/ | */ | ||||
public function isReadBufferEmpty() { | public function isReadBufferEmpty() { | ||||
return !strlen($this->stdout); | return !$this->getStdoutBufferLength(); | ||||
} | } | ||||
/** | /** | ||||
* Determine if the write buffer is empty. | * Determine if the write buffer is empty. | ||||
* | * | ||||
* @return bool True if the write buffer is empty. | * @return bool True if the write buffer is empty. | ||||
* @task internal | * @task internal | ||||
▲ Show 20 Lines • Show All 265 Lines • ▼ Show 20 Lines | public function isReady() { | ||||
// arrives between our last read and the process exiting. | // arrives between our last read and the process exiting. | ||||
$status = $this->procGetStatus(); | $status = $this->procGetStatus(); | ||||
$read_buffer_size = $this->readBufferSize; | $read_buffer_size = $this->readBufferSize; | ||||
$max_stdout_read_bytes = PHP_INT_MAX; | $max_stdout_read_bytes = PHP_INT_MAX; | ||||
$max_stderr_read_bytes = PHP_INT_MAX; | $max_stderr_read_bytes = PHP_INT_MAX; | ||||
if ($read_buffer_size !== null) { | if ($read_buffer_size !== null) { | ||||
$max_stdout_read_bytes = $read_buffer_size - strlen($this->stdout); | $stdout_len = $this->getStdoutBufferLength(); | ||||
$max_stderr_read_bytes = $read_buffer_size - strlen($this->stderr); | $stderr_len = $this->getStderrBufferLength(); | ||||
$max_stdout_read_bytes = $read_buffer_size - $stdout_len; | |||||
$max_stderr_read_bytes = $read_buffer_size - $stderr_len; | |||||
} | } | ||||
if ($max_stdout_read_bytes > 0) { | if ($max_stdout_read_bytes > 0) { | ||||
$this->stdout .= $this->readAndDiscard( | $this->stdout .= $this->readAndDiscard( | ||||
$stdout, | $stdout, | ||||
$this->getStdoutSizeLimit() - strlen($this->stdout), | $this->getStdoutSizeLimit() - $this->getStdoutBufferLength(), | ||||
'stdout', | 'stdout', | ||||
$max_stdout_read_bytes); | $max_stdout_read_bytes); | ||||
} | } | ||||
if ($max_stderr_read_bytes > 0) { | if ($max_stderr_read_bytes > 0) { | ||||
$this->stderr .= $this->readAndDiscard( | $this->stderr .= $this->readAndDiscard( | ||||
$stderr, | $stderr, | ||||
$this->getStderrSizeLimit() - strlen($this->stderr), | $this->getStderrSizeLimit() - $this->getStderrBufferLength(), | ||||
'stderr', | 'stderr', | ||||
$max_stderr_read_bytes); | $max_stderr_read_bytes); | ||||
} | } | ||||
$is_done = false; | $is_done = false; | ||||
if (!$status['running']) { | if (!$status['running']) { | ||||
// We may still have unread bytes on stdout or stderr, particularly if | // We may still have unread bytes on stdout or stderr, particularly if | ||||
// this future is being buffered and streamed. If we do, we don't want to | // this future is being buffered and streamed. If we do, we don't want to | ||||
▲ Show 20 Lines • Show All 224 Lines • ▼ Show 20 Lines | if ($this->hasResult()) { | ||||
$err = null; | $err = null; | ||||
} | } | ||||
return array( | return array( | ||||
'err' => $err, | 'err' => $err, | ||||
); | ); | ||||
} | } | ||||
private function getStdoutBufferLength() { | |||||
if ($this->stdout === null) { | |||||
return 0; | |||||
} | |||||
return strlen($this->stdout); | |||||
} | |||||
private function getStderrBufferLength() { | |||||
if ($this->stderr === null) { | |||||
return 0; | |||||
} | |||||
return strlen($this->stderr); | |||||
} | |||||
} | } |
Content licensed under Creative Commons Attribution-ShareAlike 4.0 (CC-BY-SA) unless otherwise noted; code licensed under Apache 2.0 or other open source licenses. · CC BY-SA 4.0 · Apache 2.0