mirror of
https://we.phorge.it/source/arcanist.git
synced 2024-11-25 16:22:42 +01:00
When recent PHP raises a "broken pipe" error in ExecFuture, treat it as a blocked stdin
Summary: Ref T13528. If we start a subprocess that immediately exits and then write to it, we can get a broken pipe error. Recent versions of PHP appear to raise this as an actual warning, and recent changes upgrade the warning to a runtime exception. I can't find any way to tell if the RuntimeException is a broken pipe or something else, except by examining the text of the error string. At least for now, treat this like a "blocked pipe" condition. Since the subprocess has exited and the bytes didn't write, this should generally be reasonable. Test Plan: - Viewed a file in Paste with an extension that Pygments does not have a lexer for. - This causes Pygments to exit immediately with an "unrecognized lexer" error. This closes the pipe, and the next write will fail with a broken pipe error. - Before patch: fatal on broken pipe. - After patch: clean resolution of the future and error condition. Maniphest Tasks: T13528 Differential Revision: https://secure.phabricator.com/D21199
This commit is contained in:
parent
a77cfb023d
commit
5448fe2165
1 changed files with 11 additions and 1 deletions
|
@ -713,7 +713,17 @@ final class ExecFuture extends PhutilExecutableFuture {
|
||||||
while (isset($this->stdin) && $this->stdin->getByteLength()) {
|
while (isset($this->stdin) && $this->stdin->getByteLength()) {
|
||||||
$write_segment = $this->stdin->getAnyPrefix();
|
$write_segment = $this->stdin->getAnyPrefix();
|
||||||
|
|
||||||
|
try {
|
||||||
$bytes = fwrite($stdin, $write_segment);
|
$bytes = fwrite($stdin, $write_segment);
|
||||||
|
} catch (RuntimeException $ex) {
|
||||||
|
// If the subprocess has exited, we may get a broken pipe error here
|
||||||
|
// in recent versions of PHP. There does not seem to be any way to
|
||||||
|
// get the actual error code other than reading the exception string.
|
||||||
|
|
||||||
|
// For now, treat this as if writes are blocked.
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if ($bytes === false) {
|
if ($bytes === false) {
|
||||||
throw new Exception(pht('Unable to write to stdin!'));
|
throw new Exception(pht('Unable to write to stdin!'));
|
||||||
} else if ($bytes) {
|
} else if ($bytes) {
|
||||||
|
|
Loading…
Reference in a new issue