Changeset View
Changeset View
Standalone View
Standalone View
src/future/exec/ExecFuture.php
Show All 13 Lines | |||||
* | * | ||||
* @task create Creating ExecFutures | * @task create Creating ExecFutures | ||||
* @task resolve Resolving Execution | * @task resolve Resolving Execution | ||||
* @task config Configuring Execution | * @task config Configuring Execution | ||||
* @task info Command Information | * @task info Command Information | ||||
* @task interact Interacting With Commands | * @task interact Interacting With Commands | ||||
* @task internal Internals | * @task internal Internals | ||||
*/ | */ | ||||
final class ExecFuture extends Future { | final class ExecFuture extends PhutilExecutableFuture { | ||||
private $pipes = array(); | private $pipes = array(); | ||||
private $proc = null; | private $proc = null; | ||||
private $start = null; | private $start = null; | ||||
private $timeout = null; | private $timeout = null; | ||||
private $procStatus = null; | private $procStatus = null; | ||||
private $stdout = null; | private $stdout = null; | ||||
private $stderr = null; | private $stderr = null; | ||||
private $stdin = null; | private $stdin = null; | ||||
private $closePipe = true; | private $closePipe = true; | ||||
private $stdoutPos = 0; | private $stdoutPos = 0; | ||||
private $stderrPos = 0; | private $stderrPos = 0; | ||||
private $command = null; | private $command = null; | ||||
private $env = null; | |||||
private $cwd; | |||||
private $readBufferSize; | private $readBufferSize; | ||||
private $stdoutSizeLimit = PHP_INT_MAX; | private $stdoutSizeLimit = PHP_INT_MAX; | ||||
private $stderrSizeLimit = PHP_INT_MAX; | private $stderrSizeLimit = PHP_INT_MAX; | ||||
private $profilerCallID; | private $profilerCallID; | ||||
private $killedByTimeout; | private $killedByTimeout; | ||||
▲ Show 20 Lines • Show All 128 Lines • ▼ Show 20 Lines | /* -( Configuring Execution )---------------------------------------------- */ | ||||
*/ | */ | ||||
public function setReadBufferSize($read_buffer_size) { | public function setReadBufferSize($read_buffer_size) { | ||||
$this->readBufferSize = $read_buffer_size; | $this->readBufferSize = $read_buffer_size; | ||||
return $this; | return $this; | ||||
} | } | ||||
/** | /** | ||||
* Set the current working directory to use when executing the command. | |||||
* | |||||
* @param string Directory to set as CWD before executing the command. | |||||
* @return this | |||||
* @task config | |||||
*/ | |||||
public function setCWD($cwd) { | |||||
$this->cwd = $cwd; | |||||
return $this; | |||||
} | |||||
/** | |||||
* Set the environment variables to use when executing the command. | |||||
* | |||||
* @param array Environment variables to use when executing the command. | |||||
* @return this | |||||
* @task config | |||||
*/ | |||||
public function setEnv($env, $wipe_process_env = false) { | |||||
if ($wipe_process_env) { | |||||
$this->env = $env; | |||||
} else { | |||||
$this->env = $env + $_ENV; | |||||
} | |||||
return $this; | |||||
} | |||||
/** | |||||
* Set the value of a specific environmental variable for this command. | |||||
* | |||||
* @param string Environmental variable name. | |||||
* @param string|null New value, or null to remove this variable. | |||||
* @return this | |||||
* @task config | |||||
*/ | |||||
public function updateEnv($key, $value) { | |||||
if (!is_array($this->env)) { | |||||
$this->env = $_ENV; | |||||
} | |||||
if ($value === null) { | |||||
unset($this->env[$key]); | |||||
} else { | |||||
$this->env[$key] = $value; | |||||
} | |||||
return $this; | |||||
} | |||||
/** | |||||
* Set whether to use non-blocking streams on Windows. | * Set whether to use non-blocking streams on Windows. | ||||
* | * | ||||
* @param bool Whether to use non-blocking streams. | * @param bool Whether to use non-blocking streams. | ||||
* @return this | * @return this | ||||
* @task config | * @task config | ||||
*/ | */ | ||||
public function setUseWindowsFileStreams($use_streams) { | public function setUseWindowsFileStreams($use_streams) { | ||||
if (phutil_is_windows()) { | if (phutil_is_windows()) { | ||||
▲ Show 20 Lines • Show All 409 Lines • ▼ Show 20 Lines | if (!$this->pipes) { | ||||
// looks like `command" "path to my file" "something something` which is | // looks like `command" "path to my file" "something something` which is | ||||
// clearly wrong. By surrounding the command string with quotes we can | // clearly wrong. By surrounding the command string with quotes we can | ||||
// be sure this process is harmless. | // be sure this process is harmless. | ||||
if (strpos($unmasked_command, '"') !== false) { | if (strpos($unmasked_command, '"') !== false) { | ||||
$unmasked_command = '"'.$unmasked_command.'"'; | $unmasked_command = '"'.$unmasked_command.'"'; | ||||
} | } | ||||
} | } | ||||
if ($this->hasEnv()) { | |||||
// NOTE: Convert all the environmental variables we're going to pass | $env = $this->getEnv(); | ||||
// into strings before we install PhutilErrorTrap. If something in here | |||||
// is really an object which is going to throw when we try to turn it | |||||
// into a string, we want the exception to escape here -- not after we | |||||
// start trapping errors. | |||||
$env = $this->env; | |||||
if ($env !== null) { | |||||
foreach ($env as $key => $value) { | |||||
$env[$key] = (string)$value; | |||||
} | |||||
} | |||||
// Same for the working directory. | |||||
if ($this->cwd === null) { | |||||
$cwd = null; | |||||
} else { | } else { | ||||
$cwd = (string)$this->cwd; | $env = null; | ||||
} | } | ||||
$cwd = $this->getCWD(); | |||||
// NOTE: See note above about Phage. | // NOTE: See note above about Phage. | ||||
if (class_exists('PhutilErrorTrap')) { | if (class_exists('PhutilErrorTrap')) { | ||||
$trap = new PhutilErrorTrap(); | $trap = new PhutilErrorTrap(); | ||||
} else { | } else { | ||||
$trap = null; | $trap = null; | ||||
} | } | ||||
$spec = self::$descriptorSpec; | $spec = self::$descriptorSpec; | ||||
▲ Show 20 Lines • Show All 282 Lines • Show Last 20 Lines |