Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F15426153
D18606.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
4 KB
Referenced Files
None
Subscribers
None
D18606.diff
View Options
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
Details
Attached
Mime Type
text/plain
Expires
Mar 24 2025, 7:29 AM (4 w, 2 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7382209
Default Alt Text
D18606.diff (4 KB)
Attached To
Mode
D18606: Allow setting file descriptors on ExecFutures
Attached
Detach File
Event Timeline
Log In to Comment