Merge "adb: win32: fix adb shell" am: 524716889b
am: ecdf5f3947
am: acab0b0054
* commit 'acab0b00544f11bd0c95478b1165e5d4831884c4':
adb: win32: fix adb shell
This commit is contained in:
commit
f99c144c15
1 changed files with 36 additions and 86 deletions
|
@ -2546,15 +2546,14 @@ int unix_isatty(int fd) {
|
|||
return _get_console_handle(fd) ? 1 : 0;
|
||||
}
|
||||
|
||||
// Read an input record from the console; one that should be processed.
|
||||
static bool _get_interesting_input_record_uncached(const HANDLE console,
|
||||
INPUT_RECORD* const input_record) {
|
||||
// Get the next KEY_EVENT_RECORD that should be processed.
|
||||
static bool _get_key_event_record(const HANDLE console, INPUT_RECORD* const input_record) {
|
||||
for (;;) {
|
||||
DWORD read_count = 0;
|
||||
memset(input_record, 0, sizeof(*input_record));
|
||||
if (!ReadConsoleInputA(console, input_record, 1, &read_count)) {
|
||||
D("_get_interesting_input_record_uncached: ReadConsoleInputA() "
|
||||
"failed: %s\n", SystemErrorCodeToString(GetLastError()).c_str());
|
||||
D("_get_key_event_record: ReadConsoleInputA() failed: %s\n",
|
||||
SystemErrorCodeToString(GetLastError()).c_str());
|
||||
errno = EIO;
|
||||
return false;
|
||||
}
|
||||
|
@ -2580,28 +2579,6 @@ static bool _get_interesting_input_record_uncached(const HANDLE console,
|
|||
}
|
||||
}
|
||||
|
||||
// Cached input record (in case _console_read() is passed a buffer that doesn't
|
||||
// have enough space to fit wRepeatCount number of key sequences). A non-zero
|
||||
// wRepeatCount indicates that a record is cached.
|
||||
static INPUT_RECORD _win32_input_record;
|
||||
|
||||
// Get the next KEY_EVENT_RECORD that should be processed.
|
||||
static KEY_EVENT_RECORD* _get_key_event_record(const HANDLE console) {
|
||||
// If nothing cached, read directly from the console until we get an
|
||||
// interesting record.
|
||||
if (_win32_input_record.Event.KeyEvent.wRepeatCount == 0) {
|
||||
if (!_get_interesting_input_record_uncached(console,
|
||||
&_win32_input_record)) {
|
||||
// There was an error, so make sure wRepeatCount is zero because
|
||||
// that signifies no cached input record.
|
||||
_win32_input_record.Event.KeyEvent.wRepeatCount = 0;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return &_win32_input_record.Event.KeyEvent;
|
||||
}
|
||||
|
||||
static __inline__ bool _is_shift_pressed(const DWORD control_key_state) {
|
||||
return (control_key_state & SHIFT_PRESSED) != 0;
|
||||
}
|
||||
|
@ -2946,16 +2923,34 @@ size_t _escape_prefix(char* const buf, const size_t len) {
|
|||
return len + 1;
|
||||
}
|
||||
|
||||
// Writes to buffer buf (of length len), returning number of bytes written or
|
||||
// -1 on error. Never returns zero because Win32 consoles are never 'closed'
|
||||
// (as far as I can tell).
|
||||
// Internal buffer to satisfy future _console_read() calls.
|
||||
static std::vector<char> g_console_input_buffer;
|
||||
|
||||
// Writes to buffer buf (of length len), returning number of bytes written or -1 on error. Never
|
||||
// returns zero on console closure because Win32 consoles are never 'closed' (as far as I can tell).
|
||||
static int _console_read(const HANDLE console, void* buf, size_t len) {
|
||||
for (;;) {
|
||||
KEY_EVENT_RECORD* const key_event = _get_key_event_record(console);
|
||||
if (key_event == NULL) {
|
||||
// Read of zero bytes should not block waiting for something from the console.
|
||||
if (len == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Flush as much as possible from input buffer.
|
||||
if (!g_console_input_buffer.empty()) {
|
||||
const int bytes_read = std::min(len, g_console_input_buffer.size());
|
||||
memcpy(buf, g_console_input_buffer.data(), bytes_read);
|
||||
const auto begin = g_console_input_buffer.begin();
|
||||
g_console_input_buffer.erase(begin, begin + bytes_read);
|
||||
return bytes_read;
|
||||
}
|
||||
|
||||
// Read from the actual console. This may block until input.
|
||||
INPUT_RECORD input_record;
|
||||
if (!_get_key_event_record(console, &input_record)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
KEY_EVENT_RECORD* const key_event = &input_record.Event.KeyEvent;
|
||||
const WORD vk = key_event->wVirtualKeyCode;
|
||||
const CHAR ch = key_event->uChar.AsciiChar;
|
||||
const DWORD control_key_state = _normalize_altgr_control_key_state(
|
||||
|
@ -3133,7 +3128,12 @@ static int _console_read(const HANDLE console, void* buf, size_t len) {
|
|||
break;
|
||||
|
||||
case 0x32: // 2
|
||||
case 0x33: // 3
|
||||
case 0x34: // 4
|
||||
case 0x35: // 5
|
||||
case 0x36: // 6
|
||||
case 0x37: // 7
|
||||
case 0x38: // 8
|
||||
case VK_OEM_MINUS: // -_
|
||||
{
|
||||
seqbuflen = _get_control_character(seqbuf, key_event,
|
||||
|
@ -3149,25 +3149,6 @@ static int _console_read(const HANDLE console, void* buf, size_t len) {
|
|||
}
|
||||
break;
|
||||
|
||||
case 0x33: // 3
|
||||
case 0x34: // 4
|
||||
case 0x35: // 5
|
||||
case 0x37: // 7
|
||||
case 0x38: // 8
|
||||
{
|
||||
seqbuflen = _get_control_character(seqbuf, key_event,
|
||||
control_key_state);
|
||||
|
||||
// If Alt is pressed and it isn't Ctrl-Alt-ShiftUp, then
|
||||
// prefix with escape.
|
||||
if (_is_alt_pressed(control_key_state) &&
|
||||
!(_is_ctrl_pressed(control_key_state) &&
|
||||
!_is_shift_pressed(control_key_state))) {
|
||||
seqbuflen = _escape_prefix(seqbuf, seqbuflen);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x41: // a
|
||||
case 0x42: // b
|
||||
case 0x43: // c
|
||||
|
@ -3296,46 +3277,15 @@ static int _console_read(const HANDLE console, void* buf, size_t len) {
|
|||
// event.
|
||||
D("_console_read: unknown virtual key code: %d, enhanced: %s",
|
||||
vk, _is_enhanced_key(control_key_state) ? "true" : "false");
|
||||
key_event->wRepeatCount = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
int bytesRead = 0;
|
||||
|
||||
// put output wRepeatCount times into buf/len
|
||||
while (key_event->wRepeatCount > 0) {
|
||||
if (len >= outlen) {
|
||||
// Write to buf/len
|
||||
memcpy(buf, out, outlen);
|
||||
buf = (void*)((char*)buf + outlen);
|
||||
len -= outlen;
|
||||
bytesRead += outlen;
|
||||
|
||||
// consume the input
|
||||
--key_event->wRepeatCount;
|
||||
} else {
|
||||
// Not enough space, so just leave it in _win32_input_record
|
||||
// for a subsequent retrieval.
|
||||
if (bytesRead == 0) {
|
||||
// We didn't write anything because there wasn't enough
|
||||
// space to even write one sequence. This should never
|
||||
// happen if the caller uses sensible buffer sizes
|
||||
// (i.e. >= maximum sequence length which is probably a
|
||||
// few bytes long).
|
||||
D("_console_read: no buffer space to write one sequence; "
|
||||
"buffer: %ld, sequence: %ld\n", (long)len,
|
||||
(long)outlen);
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
} else {
|
||||
// Stop trying to write to buf/len, just return whatever
|
||||
// we wrote so far.
|
||||
break;
|
||||
}
|
||||
}
|
||||
// put output wRepeatCount times into g_console_input_buffer
|
||||
while (key_event->wRepeatCount-- > 0) {
|
||||
g_console_input_buffer.insert(g_console_input_buffer.end(), out, out + outlen);
|
||||
}
|
||||
|
||||
return bytesRead;
|
||||
// Loop around and try to flush g_console_input_buffer
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue