Changeset View
Changeset View
Standalone View
Standalone View
src/future/exec/ExecFuture.php
Show First 20 Lines • Show All 303 Lines • ▼ Show 20 Lines | /* -( Resolving Execution )------------------------------------------------ */ | ||||
* list($stdout, $stderr) = $future->resolvex(); | * list($stdout, $stderr) = $future->resolvex(); | ||||
* | * | ||||
* @param float Optional timeout after which resolution will pause and | * @param float Optional timeout after which resolution will pause and | ||||
* execution will return to the caller. | * execution will return to the caller. | ||||
* @return pair <$stdout, $stderr> pair. | * @return pair <$stdout, $stderr> pair. | ||||
* @task resolve | * @task resolve | ||||
*/ | */ | ||||
public function resolvex() { | public function resolvex() { | ||||
list($err, $stdout, $stderr) = $this->resolve(); | $result = $this->resolve(); | ||||
if ($err) { | return $this->raiseResultError($result); | ||||
$cmd = $this->getCommand(); | |||||
if ($this->getWasKilledByTimeout()) { | |||||
// NOTE: The timeout can be a float and PhutilNumber only handles | |||||
// integers, so just use "%s" to render it. | |||||
$message = pht( | |||||
'Command killed by timeout after running for more than %s seconds.', | |||||
$this->terminateTimeout); | |||||
} else { | |||||
$message = pht('Command failed with error #%d!', $err); | |||||
} | } | ||||
throw new CommandException( | |||||
$message, | |||||
$cmd, | |||||
$err, | |||||
$stdout, | |||||
$stderr); | |||||
} | |||||
return array($stdout, $stderr); | |||||
} | |||||
/** | /** | ||||
* Resolve a command you expect to return valid JSON. Works like | * Resolve a command you expect to return valid JSON. Works like | ||||
* @{method:resolvex}, but also throws if stderr is nonempty, or stdout is not | * @{method:resolvex}, but also throws if stderr is nonempty, or stdout is not | ||||
* valid JSON. Returns a PHP array, decoded from the JSON command output. | * valid JSON. Returns a PHP array, decoded from the JSON command output. | ||||
* | * | ||||
* @param float Optional timeout after which resolution will pause and | * @param float Optional timeout after which resolution will pause and | ||||
* execution will return to the caller. | * execution will return to the caller. | ||||
* @return array PHP array, decoded from JSON command output. | * @return array PHP array, decoded from JSON command output. | ||||
Show All 38 Lines | /* -( Resolving Execution )------------------------------------------------ */ | ||||
public function resolveKill() { | public function resolveKill() { | ||||
if (!$this->hasResult()) { | if (!$this->hasResult()) { | ||||
$signal = 9; | $signal = 9; | ||||
if ($this->proc) { | if ($this->proc) { | ||||
proc_terminate($this->proc, $signal); | proc_terminate($this->proc, $signal); | ||||
} | } | ||||
$this->closeProcess(); | |||||
$result = array( | $result = array( | ||||
128 + $signal, | 128 + $signal, | ||||
$this->stdout, | $this->stdout, | ||||
$this->stderr, | $this->stderr, | ||||
); | ); | ||||
$this->recordResult($result); | |||||
} | |||||
return $this->getResult(); | |||||
} | |||||
private function recordResult(array $result) { | |||||
$resolve_on_error = $this->getResolveOnError(); | |||||
if (!$resolve_on_error) { | |||||
$result = $this->raiseResultError($result); | |||||
} | |||||
$this->setResult($result); | $this->setResult($result); | ||||
} | |||||
$this->closeProcess(); | private function raiseResultError($result) { | ||||
list($err, $stdout, $stderr) = $result; | |||||
if ($err) { | |||||
$cmd = $this->getCommand(); | |||||
if ($this->getWasKilledByTimeout()) { | |||||
// NOTE: The timeout can be a float and PhutilNumber only handles | |||||
// integers, so just use "%s" to render it. | |||||
$message = pht( | |||||
'Command killed by timeout after running for more than %s seconds.', | |||||
$this->terminateTimeout); | |||||
} else { | |||||
$message = pht('Command failed with error #%d!', $err); | |||||
} | } | ||||
return $this->getResult(); | throw new CommandException( | ||||
$message, | |||||
$cmd, | |||||
$err, | |||||
$stdout, | |||||
$stderr); | |||||
} | |||||
return array($stdout, $stderr); | |||||
} | } | ||||
/* -( Internals )---------------------------------------------------------- */ | /* -( Internals )---------------------------------------------------------- */ | ||||
/** | /** | ||||
* Provides read sockets to the future core. | * Provides read sockets to the future core. | ||||
▲ Show 20 Lines • Show All 217 Lines • ▼ Show 20 Lines | if (!$this->pipes) { | ||||
$result = array( | $result = array( | ||||
1, | 1, | ||||
'', | '', | ||||
pht( | pht( | ||||
'Call to "proc_open()" to open a subprocess failed: %s', | 'Call to "proc_open()" to open a subprocess failed: %s', | ||||
$err), | $err), | ||||
); | ); | ||||
$this->setResult($result); | $this->recordResult($result); | ||||
return true; | return true; | ||||
} | } | ||||
if ($is_windows) { | if ($is_windows) { | ||||
$stdout_handle = fopen($stdout_file, 'rb'); | $stdout_handle = fopen($stdout_file, 'rb'); | ||||
if (!$stdout_handle) { | if (!$stdout_handle) { | ||||
throw new Exception( | throw new Exception( | ||||
▲ Show 20 Lines • Show All 127 Lines • ▼ Show 20 Lines | if ($is_done) { | ||||
} | } | ||||
$result = array( | $result = array( | ||||
$err, | $err, | ||||
$this->stdout, | $this->stdout, | ||||
$signal_info.$this->stderr, | $signal_info.$this->stderr, | ||||
); | ); | ||||
$this->setResult($result); | $this->recordResult($result); | ||||
$this->closeProcess(); | $this->closeProcess(); | ||||
return true; | return true; | ||||
} | } | ||||
$elapsed = (microtime(true) - $this->start); | $elapsed = (microtime(true) - $this->start); | ||||
if ($this->terminateTimeout && ($elapsed >= $this->terminateTimeout)) { | if ($this->terminateTimeout && ($elapsed >= $this->terminateTimeout)) { | ||||
▲ Show 20 Lines • Show All 181 Lines • Show Last 20 Lines |