Page MenuHomePhabricator

D18606.diff
No OneTemporary

D18606.diff

diff --git a/src/future/exec/ExecFuture.php b/src/future/exec/ExecFuture.php
--- a/src/future/exec/ExecFuture.php
+++ b/src/future/exec/ExecFuture.php
@@ -56,6 +56,8 @@
2 => array('pipe', 'w'), // stderr
);
+ private $descriptors;
+
/* -( Creating ExecFutures )----------------------------------------------- */
@@ -195,6 +197,19 @@
return $this;
}
+ /**
+ * Set the file descriptors which will be passed down to the underlying
+ * process; defaults to all of the standard handles being pipes back to this
+ * class. Overrides configuration set by @{method:setUseWindowsFileStreams}.
+ *
+ * @param array As passed to `proc_open`.
+ * @return this
+ * @task config
+ */
+ public function setDescriptors($descs) {
+ $this->descriptors = $descs;
+ return $this;
+ }
/* -( Interacting With Commands )------------------------------------------ */
@@ -626,8 +641,9 @@
$trap = null;
}
- $spec = self::$descriptorSpec;
- if ($this->useWindowsFileStreams) {
+ if ($this->descriptors) {
+ $spec = $this->descriptors;
+ } else if ($this->useWindowsFileStreams) {
$this->windowsStdoutTempFile = new TempFile();
$this->windowsStderrTempFile = new TempFile();
@@ -642,6 +658,8 @@
'Unable to create temporary files for '.
'Windows stdout / stderr streams'));
}
+ } else {
+ $spec = self::$descriptorSpec;
}
$proc = @proc_open(
@@ -651,7 +669,7 @@
$cwd,
$env);
- if ($this->useWindowsFileStreams) {
+ if (!$this->descriptors && $this->useWindowsFileStreams) {
fclose($spec[1]);
fclose($spec[2]);
$pipes = array(
@@ -682,6 +700,10 @@
$err));
}
+ // If different descriptors were passed, we may have an array without
+ // values for all of its indices. Merge null values in.
+ $pipes = $pipes + array(null, null, null);
+
$this->pipes = $pipes;
$this->proc = $proc;
@@ -693,9 +715,9 @@
// through temporary files, and then use stream_select to determine
// if there's more data to read.
- if ((!stream_set_blocking($stdout, false)) ||
- (!stream_set_blocking($stderr, false)) ||
- (!stream_set_blocking($stdin, false))) {
+ if (($stdout && !stream_set_blocking($stdout, false)) ||
+ ($stderr && !stream_set_blocking($stderr, false)) ||
+ ($stdin && !stream_set_blocking($stdin, false))) {
$this->__destruct();
throw new Exception(pht('Failed to set streams nonblocking.'));
}
@@ -741,7 +763,7 @@
$max_stderr_read_bytes = $read_buffer_size - strlen($this->stderr);
}
- if ($max_stdout_read_bytes > 0) {
+ if ($max_stdout_read_bytes > 0 && $stdout) {
$this->stdout .= $this->readAndDiscard(
$stdout,
$this->getStdoutSizeLimit() - strlen($this->stdout),
@@ -749,7 +771,7 @@
$max_stdout_read_bytes);
}
- if ($max_stderr_read_bytes > 0) {
+ if ($max_stderr_read_bytes > 0 && $stderr) {
$this->stderr .= $this->readAndDiscard(
$stderr,
$this->getStderrSizeLimit() - strlen($this->stderr),
@@ -769,7 +791,7 @@
}
if ($is_done) {
- if ($this->useWindowsFileStreams) {
+ if (!$this->descriptors && $this->useWindowsFileStreams) {
fclose($stdout);
fclose($stderr);
}
diff --git a/src/future/exec/__tests__/ExecFutureTestCase.php b/src/future/exec/__tests__/ExecFutureTestCase.php
--- a/src/future/exec/__tests__/ExecFutureTestCase.php
+++ b/src/future/exec/__tests__/ExecFutureTestCase.php
@@ -152,4 +152,34 @@
$future->resolve();
}
+ public function testHigherFileDescriptors() {
+ $temp = new TempFile();
+ $future = new ExecFuture('echo yay >&3');
+ $future->setDescriptors(
+ array(
+ 0 => array('pipe', 'r'), // stdin
+ 1 => array('pipe', 'w'), // stdout
+ 2 => array('pipe', 'w'), // stderr
+ 3 => array('file', $temp, 'w'),
+ ));
+
+ list($stdout) = $future->resolvex();
+ $this->assertEqual('', $stdout);
+ $this->assertEqual("yay\n", Filesystem::readFile($temp));
+ }
+
+ public function testFeedStdin() {
+ $temp = new TempFile();
+ Filesystem::writeFile($temp, 'yay');
+ $future = new ExecFuture('cat');
+ $future->setDescriptors(
+ array(
+ 0 => array('file', $temp, 'r'), // stdin
+ 1 => array('pipe', 'w'), // stdout
+ 2 => array('pipe', 'w'), // stderr
+ ));
+
+ list($stdout) = $future->resolvex();
+ $this->assertEqual('yay', $stdout);
+ }
}

File Metadata

Mime Type
text/plain
Expires
Sun, May 12, 2:31 PM (1 w, 4 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6291386
Default Alt Text
D18606.diff (4 KB)

Event Timeline