Fix error reporting in Input::writeKeyboard()
write(2) only sets errno on failure; a successful call leaves it
unchanged. We had been being using errno to determine whether or not
the write succeeded, but weren't zeroing it before the call and hence
could end up spuriously reporting failure from writeKeyboard() even when
the write actually succeeded.
That false report can in turn cause sendWakeupPacket() to not send the
key release after its XK_Shift_L key press, leading to the host thinking
the shift key is being held down, which among other minor bits of
confusion can cause a boot hang (Ubuntu's GRUB, for example, is patched
to interpret a held shift key as a signal from the user to interrupt its
default boot sequence and switch to an interactive menu).
We now instead just return success immediately after a complete write
and false otherwise (if we exhaust our retry attempts or hit a
non-EAGAIN failure).
Tested: verified with strace that obmc-ikvm sends both the press and the
release of the shift key in sendWakeupPacket(); Ubuntu host booted
cleanly instead of stopping at the GRUB menu.
Signed-off-by: Zev Weiss <zweiss@equinix.com>
Change-Id: Ic1229b3979690040879c7e4471ebc987878289e6
diff --git a/ikvm_input.cpp b/ikvm_input.cpp
index 480db3c..6e8ab26 100644
--- a/ikvm_input.cpp
+++ b/ikvm_input.cpp
@@ -495,7 +495,7 @@
{
if (write(keyboardFd, report, KEY_REPORT_LENGTH) == KEY_REPORT_LENGTH)
{
- break;
+ return true;
}
if (errno != EAGAIN)
@@ -515,12 +515,7 @@
retryCount--;
}
- if (!retryCount || errno)
- {
- return false;
- }
-
- return true;
+ return false;
}
void Input::writePointer(const uint8_t *report)