1
0
Fork 0
mirror of https://we.phorge.it/source/arcanist.git synced 2024-11-25 08:12:40 +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:
epriestley 2020-05-01 06:59:05 -07:00
parent a77cfb023d
commit 5448fe2165

View file

@ -713,7 +713,17 @@ final class ExecFuture extends PhutilExecutableFuture {
while (isset($this->stdin) && $this->stdin->getByteLength()) {
$write_segment = $this->stdin->getAnyPrefix();
try {
$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) {
throw new Exception(pht('Unable to write to stdin!'));
} else if ($bytes) {