1
0
Fork 0
mirror of https://we.phorge.it/source/arcanist.git synced 2024-11-21 22:32:41 +01:00

On Windows, don't try to set "stdin" nonblocking, as it does not work

Summary:
See <https://discourse.phabricator-community.org/t/arc-land-fail-unable-to-set-stdin-nonblocking/4006/>.

See also <https://bugs.php.net/bug.php?id=34972>.

Note that you can't ^C during a prompt (or at any other time) in Windows currently, see T13549.

Test Plan: On Windows, hit a prompt in "arc land", then answered it successfully.

Differential Revision: https://secure.phabricator.com/D21358
This commit is contained in:
epriestley 2020-06-12 14:16:36 -07:00
parent 1e09a0ee7e
commit 33dfa859d8

View file

@ -86,18 +86,22 @@ final class ArcanistPrompt
throw $ex; throw $ex;
} }
// NOTE: We're making stdin nonblocking so that we can respond to signals
// immediately. If we don't, and you ^C during a prompt, the program does
// not handle the signal until fgets() returns.
$stdin = fopen('php://stdin', 'r'); $stdin = fopen('php://stdin', 'r');
if (!$stdin) { if (!$stdin) {
throw new Exception(pht('Failed to open stdin for reading.')); throw new Exception(pht('Failed to open stdin for reading.'));
} }
$ok = stream_set_blocking($stdin, false); // NOTE: We're making stdin nonblocking so that we can respond to signals
if (!$ok) { // immediately. If we don't, and you ^C during a prompt, the program does
throw new Exception(pht('Unable to set stdin nonblocking.')); // not handle the signal until fgets() returns.
// On Windows, we skip this because stdin can not be made nonblocking.
if (!phutil_is_windows()) {
$ok = stream_set_blocking($stdin, false);
if (!$ok) {
throw new Exception(pht('Unable to set stdin nonblocking.'));
}
} }
echo "\n"; echo "\n";
@ -117,44 +121,48 @@ final class ArcanistPrompt
$query, $query,
$options); $options);
while (true) { $is_saved = false;
$is_saved = false;
$read = array($stdin); if (phutil_is_windows()) {
$write = array(); $response = fgets($stdin);
$except = array(); } else {
$ok = @stream_select($read, $write, $except, 1);
if ($ok === false) {
// NOTE: We may be interrupted by a system call, particularly if
// the window is resized while a prompt is shown and the terminal
// sends SIGWINCH.
// If we are, just continue below and try to read from stdin. If
// we were interrupted, we should read nothing and continue
// normally. If the pipe is broken, the read should fail.
}
$response = '';
while (true) { while (true) {
$bytes = fread($stdin, 8192); $read = array($stdin);
if ($bytes === false) { $write = array();
throw new Exception( $except = array();
pht('fread() from stdin failed with an error.'));
$ok = @stream_select($read, $write, $except, 1);
if ($ok === false) {
// NOTE: We may be interrupted by a system call, particularly if
// the window is resized while a prompt is shown and the terminal
// sends SIGWINCH.
// If we are, just continue below and try to read from stdin. If
// we were interrupted, we should read nothing and continue
// normally. If the pipe is broken, the read should fail.
} }
if (!strlen($bytes)) { $response = '';
break; while (true) {
$bytes = fread($stdin, 8192);
if ($bytes === false) {
throw new Exception(
pht('fread() from stdin failed with an error.'));
}
if (!strlen($bytes)) {
break;
}
$response .= $bytes;
} }
$response .= $bytes; if (!strlen($response)) {
} continue;
}
if (!strlen($response)) { break;
continue;
} }
break;
} }
$response = trim($response); $response = trim($response);