blob: cbbfdc475e3e55ae178c57475adbc1d86f21b74a [file] [log] [blame]
Eddie James21b177e2018-12-11 13:14:46 -06001#include "ikvm_input.hpp"
2
3#include "ikvm_server.hpp"
4
5#include <err.h>
6#include <errno.h>
7#include <fcntl.h>
8#include <rfb/keysym.h>
9#include <sys/stat.h>
10#include <sys/types.h>
11
12#include <phosphor-logging/elog-errors.hpp>
13#include <phosphor-logging/elog.hpp>
14#include <phosphor-logging/log.hpp>
15#include <xyz/openbmc_project/Common/File/error.hpp>
16
Jae Hyun Yoo7dfac9f2019-01-15 10:14:59 -080017#include "scancodes.hpp"
Eddie James21b177e2018-12-11 13:14:46 -060018
Jae Hyun Yooc11257d2020-07-22 23:39:18 -070019namespace fs = std::filesystem;
20
Eddie James21b177e2018-12-11 13:14:46 -060021namespace ikvm
22{
23
24using namespace phosphor::logging;
25using namespace sdbusplus::xyz::openbmc_project::Common::File::Error;
26
Jae Hyun Yoo7dfac9f2019-01-15 10:14:59 -080027Input::Input(const std::string& kbdPath, const std::string& ptrPath) :
Jae Hyun Yoo673ac2e2020-07-30 00:29:19 -070028 keyboardFd(-1), pointerFd(-1), keyboardReport{0}, pointerReport{0},
29 keyboardPath(kbdPath), pointerPath(ptrPath)
Eddie James21b177e2018-12-11 13:14:46 -060030{
Jae Hyun Yooc11257d2020-07-22 23:39:18 -070031 hidUdcStream.exceptions(std::ofstream::failbit | std::ofstream::badbit);
32 hidUdcStream.open(hidUdcPath, std::ios::out | std::ios::app);
33}
34
35Input::~Input()
36{
37 if (keyboardFd >= 0)
38 {
39 close(keyboardFd);
40 }
41
42 if (pointerFd >= 0)
43 {
44 close(pointerFd);
45 }
46
47 disconnect();
48 hidUdcStream.close();
49}
50
51void Input::connect()
52{
53 try
54 {
55 for (const auto& port : fs::directory_iterator(usbVirtualHubPath))
56 {
57 if (fs::is_directory(port) && !fs::is_symlink(port) &&
58 !fs::exists(port.path() / "gadget/suspended"))
59 {
60 const std::string portId = port.path().filename();
61 hidUdcStream << portId << std::endl;
62 break;
63 }
64 }
65 }
66 catch (fs::filesystem_error& e)
67 {
68 log<level::ERR>("Failed to search USB virtual hub port",
69 entry("ERROR=%s", e.what()));
70 return;
71 }
72 catch (std::ofstream::failure& e)
73 {
74 log<level::ERR>("Failed to connect HID gadget",
75 entry("ERROR=%s", e.what()));
76 return;
77 }
78
Jae Hyun Yoo7dfac9f2019-01-15 10:14:59 -080079 if (!keyboardPath.empty())
Eddie James21b177e2018-12-11 13:14:46 -060080 {
Jae Hyun Yoo673ac2e2020-07-30 00:29:19 -070081 keyboardFd = open(keyboardPath.c_str(),
82 O_RDWR | O_CLOEXEC | O_NONBLOCK);
Jae Hyun Yoo7dfac9f2019-01-15 10:14:59 -080083 if (keyboardFd < 0)
84 {
85 log<level::ERR>("Failed to open input device",
86 entry("PATH=%s", keyboardPath.c_str()),
87 entry("ERROR=%s", strerror(errno)));
88 elog<Open>(xyz::openbmc_project::Common::File::Open::ERRNO(errno),
89 xyz::openbmc_project::Common::File::Open::PATH(
90 keyboardPath.c_str()));
91 }
Eddie James21b177e2018-12-11 13:14:46 -060092 }
93
Jae Hyun Yoo7dfac9f2019-01-15 10:14:59 -080094 if (!pointerPath.empty())
95 {
Eddie James4749f932019-04-18 11:06:39 -050096 pointerFd = open(pointerPath.c_str(), O_RDWR | O_CLOEXEC | O_NONBLOCK);
Jae Hyun Yoo7dfac9f2019-01-15 10:14:59 -080097 if (pointerFd < 0)
98 {
99 log<level::ERR>("Failed to open input device",
100 entry("PATH=%s", pointerPath.c_str()),
101 entry("ERROR=%s", strerror(errno)));
102 elog<Open>(xyz::openbmc_project::Common::File::Open::ERRNO(errno),
103 xyz::openbmc_project::Common::File::Open::PATH(
104 pointerPath.c_str()));
105 }
106 }
Eddie James21b177e2018-12-11 13:14:46 -0600107}
108
Jae Hyun Yooc11257d2020-07-22 23:39:18 -0700109void Input::disconnect()
Eddie James21b177e2018-12-11 13:14:46 -0600110{
Jae Hyun Yoo7dfac9f2019-01-15 10:14:59 -0800111 if (keyboardFd >= 0)
112 {
113 close(keyboardFd);
Jae Hyun Yooc11257d2020-07-22 23:39:18 -0700114 keyboardFd = -1;
Jae Hyun Yoo7dfac9f2019-01-15 10:14:59 -0800115 }
116
117 if (pointerFd >= 0)
118 {
119 close(pointerFd);
Jae Hyun Yooc11257d2020-07-22 23:39:18 -0700120 pointerFd = -1;
121 }
122
123 try
124 {
125 hidUdcStream << "" << std::endl;
126 }
127 catch (std::ofstream::failure& e)
128 {
129 log<level::ERR>("Failed to disconnect HID gadget",
130 entry("ERROR=%s", e.what()));
Jae Hyun Yoo7dfac9f2019-01-15 10:14:59 -0800131 }
Eddie James21b177e2018-12-11 13:14:46 -0600132}
133
134void Input::keyEvent(rfbBool down, rfbKeySym key, rfbClientPtr cl)
135{
136 Server::ClientData* cd = (Server::ClientData*)cl->clientData;
137 Input* input = cd->input;
Jae Hyun Yoo673ac2e2020-07-30 00:29:19 -0700138 bool sendKeyboard = false;
139
140 if (input->keyboardFd < 0)
141 {
142 return;
143 }
Eddie James21b177e2018-12-11 13:14:46 -0600144
145 if (down)
146 {
Jae Hyun Yoo7dfac9f2019-01-15 10:14:59 -0800147 uint8_t sc = keyToScancode(key);
Eddie James21b177e2018-12-11 13:14:46 -0600148
149 if (sc)
150 {
151 if (input->keysDown.find(key) == input->keysDown.end())
152 {
Jae Hyun Yoo7dfac9f2019-01-15 10:14:59 -0800153 for (unsigned int i = 2; i < KEY_REPORT_LENGTH; ++i)
Eddie James21b177e2018-12-11 13:14:46 -0600154 {
155 if (!input->keyboardReport[i])
156 {
157 input->keyboardReport[i] = sc;
158 input->keysDown.insert(std::make_pair(key, i));
Jae Hyun Yoo673ac2e2020-07-30 00:29:19 -0700159 sendKeyboard = true;
Eddie James21b177e2018-12-11 13:14:46 -0600160 break;
161 }
162 }
163 }
164 }
165 else
166 {
Jae Hyun Yoo7dfac9f2019-01-15 10:14:59 -0800167 uint8_t mod = keyToMod(key);
Eddie James21b177e2018-12-11 13:14:46 -0600168
169 if (mod)
170 {
Jae Hyun Yoo7dfac9f2019-01-15 10:14:59 -0800171 input->keyboardReport[0] |= mod;
Jae Hyun Yoo673ac2e2020-07-30 00:29:19 -0700172 sendKeyboard = true;
Eddie James21b177e2018-12-11 13:14:46 -0600173 }
174 }
175 }
176 else
177 {
178 auto it = input->keysDown.find(key);
179
180 if (it != input->keysDown.end())
181 {
182 input->keyboardReport[it->second] = 0;
183 input->keysDown.erase(it);
Jae Hyun Yoo673ac2e2020-07-30 00:29:19 -0700184 sendKeyboard = true;
Eddie James21b177e2018-12-11 13:14:46 -0600185 }
186 else
187 {
Jae Hyun Yoo7dfac9f2019-01-15 10:14:59 -0800188 uint8_t mod = keyToMod(key);
Eddie James21b177e2018-12-11 13:14:46 -0600189
190 if (mod)
191 {
Jae Hyun Yoo7dfac9f2019-01-15 10:14:59 -0800192 input->keyboardReport[0] &= ~mod;
Jae Hyun Yoo673ac2e2020-07-30 00:29:19 -0700193 sendKeyboard = true;
Eddie James21b177e2018-12-11 13:14:46 -0600194 }
195 }
196 }
Jae Hyun Yoo673ac2e2020-07-30 00:29:19 -0700197
198 if (sendKeyboard)
199 {
200 input->writeKeyboard(input->keyboardReport);
201 }
Eddie James21b177e2018-12-11 13:14:46 -0600202}
203
204void Input::pointerEvent(int buttonMask, int x, int y, rfbClientPtr cl)
205{
206 Server::ClientData* cd = (Server::ClientData*)cl->clientData;
207 Input* input = cd->input;
208 Server* server = (Server*)cl->screen->screenData;
209 const Video& video = server->getVideo();
210
Jae Hyun Yoo673ac2e2020-07-30 00:29:19 -0700211 if (input->pointerFd < 0)
212 {
213 return;
214 }
215
Tejas Patil3fa0bfb2021-12-23 15:44:47 +0530216 if (buttonMask > 4)
217 {
218 input->pointerReport[0] = 0;
219 if (buttonMask == 8)
220 {
221 input->pointerReport[5] = 1;
222 }
223 else if (buttonMask == 16)
224 {
225 input->pointerReport[5] = 0xff;
226 }
227 }
228 else
229 {
230 input->pointerReport[0] = ((buttonMask & 0x4) >> 1) |
231 ((buttonMask & 0x2) << 1) | (buttonMask & 0x1);
232 input->pointerReport[5] = 0;
233 }
Eddie James21b177e2018-12-11 13:14:46 -0600234
235 if (x >= 0 && (unsigned int)x < video.getWidth())
236 {
Jae Hyun Yoo2bc661d2019-02-25 13:52:47 -0800237 uint16_t xx = (uint16_t)(x * (SHRT_MAX + 1) / video.getWidth());
Eddie James21b177e2018-12-11 13:14:46 -0600238
Jae Hyun Yoo7dfac9f2019-01-15 10:14:59 -0800239 memcpy(&input->pointerReport[1], &xx, 2);
Eddie James21b177e2018-12-11 13:14:46 -0600240 }
241
242 if (y >= 0 && (unsigned int)y < video.getHeight())
243 {
Jae Hyun Yoo2bc661d2019-02-25 13:52:47 -0800244 uint16_t yy = (uint16_t)(y * (SHRT_MAX + 1) / video.getHeight());
Eddie James21b177e2018-12-11 13:14:46 -0600245
Jae Hyun Yoo7dfac9f2019-01-15 10:14:59 -0800246 memcpy(&input->pointerReport[3], &yy, 2);
Eddie James21b177e2018-12-11 13:14:46 -0600247 }
248
Eddie James21b177e2018-12-11 13:14:46 -0600249 rfbDefaultPtrAddEvent(buttonMask, x, y, cl);
Jae Hyun Yoo673ac2e2020-07-30 00:29:19 -0700250 input->writePointer(input->pointerReport);
Eddie James21b177e2018-12-11 13:14:46 -0600251}
252
Jae Hyun Yoo7dfac9f2019-01-15 10:14:59 -0800253void Input::sendWakeupPacket()
Eddie James21b177e2018-12-11 13:14:46 -0600254{
Jae Hyun Yooeaf5c5b2019-02-20 15:03:17 -0800255 uint8_t wakeupReport[KEY_REPORT_LENGTH] = {0};
Jae Hyun Yoo7dfac9f2019-01-15 10:14:59 -0800256
Jae Hyun Yooeaf5c5b2019-02-20 15:03:17 -0800257 if (pointerFd >= 0)
Jae Hyun Yoo7dfac9f2019-01-15 10:14:59 -0800258 {
Jae Hyun Yooeaf5c5b2019-02-20 15:03:17 -0800259 uint16_t xy = SHRT_MAX / 2;
260
261 memcpy(&wakeupReport[1], &xy, 2);
262 memcpy(&wakeupReport[3], &xy, 2);
263
Eddie James7cf1f1d2019-09-30 15:05:16 -0500264 writePointer(wakeupReport);
Jae Hyun Yoo7dfac9f2019-01-15 10:14:59 -0800265 }
266
Jae Hyun Yooeaf5c5b2019-02-20 15:03:17 -0800267 if (keyboardFd >= 0)
Eddie James21b177e2018-12-11 13:14:46 -0600268 {
Jae Hyun Yooeaf5c5b2019-02-20 15:03:17 -0800269 memset(&wakeupReport[0], 0, KEY_REPORT_LENGTH);
270
271 wakeupReport[0] = keyToMod(XK_Shift_L);
272
Eddie James7cf1f1d2019-09-30 15:05:16 -0500273 if (!writeKeyboard(wakeupReport))
Jae Hyun Yooeaf5c5b2019-02-20 15:03:17 -0800274 {
Jae Hyun Yooeaf5c5b2019-02-20 15:03:17 -0800275 return;
276 }
277
278 wakeupReport[0] = 0;
279
Eddie James7cf1f1d2019-09-30 15:05:16 -0500280 writeKeyboard(wakeupReport);
Eddie James21b177e2018-12-11 13:14:46 -0600281 }
282}
283
Jae Hyun Yoo7dfac9f2019-01-15 10:14:59 -0800284uint8_t Input::keyToMod(rfbKeySym key)
Eddie James21b177e2018-12-11 13:14:46 -0600285{
Jae Hyun Yoo7dfac9f2019-01-15 10:14:59 -0800286 uint8_t mod = 0;
Eddie James21b177e2018-12-11 13:14:46 -0600287
288 if (key >= XK_Shift_L && key <= XK_Control_R)
289 {
290 mod = shiftCtrlMap[key - XK_Shift_L];
291 }
292 else if (key >= XK_Meta_L && key <= XK_Alt_R)
293 {
294 mod = metaAltMap[key - XK_Meta_L];
295 }
296
297 return mod;
298}
299
Jae Hyun Yoo7dfac9f2019-01-15 10:14:59 -0800300uint8_t Input::keyToScancode(rfbKeySym key)
Eddie James21b177e2018-12-11 13:14:46 -0600301{
Jae Hyun Yoo7dfac9f2019-01-15 10:14:59 -0800302 uint8_t scancode = 0;
Eddie James21b177e2018-12-11 13:14:46 -0600303
304 if ((key >= 'A' && key <= 'Z') || (key >= 'a' && key <= 'z'))
305 {
306 scancode = USBHID_KEY_A + ((key & 0x5F) - 'A');
307 }
308 else if (key >= '1' && key <= '9')
309 {
310 scancode = USBHID_KEY_1 + (key - '1');
311 }
312 else if (key >= XK_F1 && key <= XK_F12)
313 {
314 scancode = USBHID_KEY_F1 + (key - XK_F1);
315 }
Jae Hyun Yoo513d95e2019-08-20 11:26:53 -0700316 else if (key >= XK_KP_F1 && key <= XK_KP_F4)
317 {
318 scancode = USBHID_KEY_F1 + (key - XK_KP_F1);
319 }
320 else if (key >= XK_KP_1 && key <= XK_KP_9)
321 {
322 scancode = USBHID_KEY_KP_1 + (key - XK_KP_1);
323 }
Eddie James21b177e2018-12-11 13:14:46 -0600324 else
325 {
326 switch (key)
327 {
328 case XK_exclam:
329 scancode = USBHID_KEY_1;
330 break;
331 case XK_at:
332 scancode = USBHID_KEY_2;
333 break;
334 case XK_numbersign:
335 scancode = USBHID_KEY_3;
336 break;
337 case XK_dollar:
338 scancode = USBHID_KEY_4;
339 break;
340 case XK_percent:
341 scancode = USBHID_KEY_5;
342 break;
343 case XK_asciicircum:
344 scancode = USBHID_KEY_6;
345 break;
346 case XK_ampersand:
347 scancode = USBHID_KEY_7;
348 break;
349 case XK_asterisk:
350 scancode = USBHID_KEY_8;
351 break;
352 case XK_parenleft:
353 scancode = USBHID_KEY_9;
354 break;
355 case XK_0:
356 case XK_parenright:
357 scancode = USBHID_KEY_0;
358 break;
359 case XK_Return:
360 scancode = USBHID_KEY_RETURN;
361 break;
362 case XK_Escape:
363 scancode = USBHID_KEY_ESC;
364 break;
365 case XK_BackSpace:
366 scancode = USBHID_KEY_BACKSPACE;
367 break;
368 case XK_Tab:
Jae Hyun Yoo513d95e2019-08-20 11:26:53 -0700369 case XK_KP_Tab:
Eddie James21b177e2018-12-11 13:14:46 -0600370 scancode = USBHID_KEY_TAB;
371 break;
372 case XK_space:
Jae Hyun Yoo513d95e2019-08-20 11:26:53 -0700373 case XK_KP_Space:
Eddie James21b177e2018-12-11 13:14:46 -0600374 scancode = USBHID_KEY_SPACE;
375 break;
376 case XK_minus:
377 case XK_underscore:
378 scancode = USBHID_KEY_MINUS;
379 break;
380 case XK_plus:
381 case XK_equal:
382 scancode = USBHID_KEY_EQUAL;
383 break;
384 case XK_bracketleft:
385 case XK_braceleft:
386 scancode = USBHID_KEY_LEFTBRACE;
387 break;
388 case XK_bracketright:
389 case XK_braceright:
390 scancode = USBHID_KEY_RIGHTBRACE;
391 break;
392 case XK_backslash:
393 case XK_bar:
394 scancode = USBHID_KEY_BACKSLASH;
395 break;
396 case XK_colon:
397 case XK_semicolon:
398 scancode = USBHID_KEY_SEMICOLON;
399 break;
400 case XK_quotedbl:
401 case XK_apostrophe:
402 scancode = USBHID_KEY_APOSTROPHE;
403 break;
404 case XK_grave:
405 case XK_asciitilde:
406 scancode = USBHID_KEY_GRAVE;
407 break;
408 case XK_comma:
409 case XK_less:
410 scancode = USBHID_KEY_COMMA;
411 break;
412 case XK_period:
413 case XK_greater:
414 scancode = USBHID_KEY_DOT;
415 break;
416 case XK_slash:
417 case XK_question:
418 scancode = USBHID_KEY_SLASH;
419 break;
420 case XK_Caps_Lock:
421 scancode = USBHID_KEY_CAPSLOCK;
422 break;
423 case XK_Print:
424 scancode = USBHID_KEY_PRINT;
425 break;
426 case XK_Scroll_Lock:
427 scancode = USBHID_KEY_SCROLLLOCK;
428 break;
429 case XK_Pause:
430 scancode = USBHID_KEY_PAUSE;
431 break;
432 case XK_Insert:
Jae Hyun Yoo513d95e2019-08-20 11:26:53 -0700433 case XK_KP_Insert:
Eddie James21b177e2018-12-11 13:14:46 -0600434 scancode = USBHID_KEY_INSERT;
435 break;
436 case XK_Home:
Jae Hyun Yoo513d95e2019-08-20 11:26:53 -0700437 case XK_KP_Home:
Eddie James21b177e2018-12-11 13:14:46 -0600438 scancode = USBHID_KEY_HOME;
439 break;
440 case XK_Page_Up:
Jae Hyun Yoo513d95e2019-08-20 11:26:53 -0700441 case XK_KP_Page_Up:
Eddie James21b177e2018-12-11 13:14:46 -0600442 scancode = USBHID_KEY_PAGEUP;
443 break;
444 case XK_Delete:
Jae Hyun Yoo513d95e2019-08-20 11:26:53 -0700445 case XK_KP_Delete:
Eddie James21b177e2018-12-11 13:14:46 -0600446 scancode = USBHID_KEY_DELETE;
447 break;
448 case XK_End:
Jae Hyun Yoo513d95e2019-08-20 11:26:53 -0700449 case XK_KP_End:
Eddie James21b177e2018-12-11 13:14:46 -0600450 scancode = USBHID_KEY_END;
451 break;
452 case XK_Page_Down:
Jae Hyun Yoo513d95e2019-08-20 11:26:53 -0700453 case XK_KP_Page_Down:
Eddie James21b177e2018-12-11 13:14:46 -0600454 scancode = USBHID_KEY_PAGEDOWN;
455 break;
456 case XK_Right:
Jae Hyun Yoo513d95e2019-08-20 11:26:53 -0700457 case XK_KP_Right:
Eddie James21b177e2018-12-11 13:14:46 -0600458 scancode = USBHID_KEY_RIGHT;
459 break;
460 case XK_Left:
Jae Hyun Yoo513d95e2019-08-20 11:26:53 -0700461 case XK_KP_Left:
Eddie James21b177e2018-12-11 13:14:46 -0600462 scancode = USBHID_KEY_LEFT;
463 break;
464 case XK_Down:
Jae Hyun Yoo513d95e2019-08-20 11:26:53 -0700465 case XK_KP_Down:
Eddie James21b177e2018-12-11 13:14:46 -0600466 scancode = USBHID_KEY_DOWN;
467 break;
468 case XK_Up:
Jae Hyun Yoo513d95e2019-08-20 11:26:53 -0700469 case XK_KP_Up:
Eddie James21b177e2018-12-11 13:14:46 -0600470 scancode = USBHID_KEY_UP;
471 break;
472 case XK_Num_Lock:
473 scancode = USBHID_KEY_NUMLOCK;
474 break;
Jae Hyun Yoo513d95e2019-08-20 11:26:53 -0700475 case XK_KP_Enter:
476 scancode = USBHID_KEY_KP_ENTER;
477 break;
478 case XK_KP_Equal:
479 scancode = USBHID_KEY_KP_EQUAL;
480 break;
481 case XK_KP_Multiply:
482 scancode = USBHID_KEY_KP_MULTIPLY;
483 break;
484 case XK_KP_Add:
485 scancode = USBHID_KEY_KP_ADD;
486 break;
487 case XK_KP_Subtract:
488 scancode = USBHID_KEY_KP_SUBTRACT;
489 break;
490 case XK_KP_Decimal:
491 scancode = USBHID_KEY_KP_DECIMAL;
492 break;
493 case XK_KP_Divide:
494 scancode = USBHID_KEY_KP_DIVIDE;
495 break;
496 case XK_KP_0:
497 scancode = USBHID_KEY_KP_0;
498 break;
Eddie James21b177e2018-12-11 13:14:46 -0600499 }
500 }
501
502 return scancode;
503}
504
Eddie James7cf1f1d2019-09-30 15:05:16 -0500505bool Input::writeKeyboard(const uint8_t *report)
506{
Jae Hyun Yoo673ac2e2020-07-30 00:29:19 -0700507 std::unique_lock<std::mutex> lk(keyMutex);
508 uint retryCount = HID_REPORT_RETRY_MAX;
509
510 while (retryCount > 0)
Eddie James7cf1f1d2019-09-30 15:05:16 -0500511 {
Jae Hyun Yoo673ac2e2020-07-30 00:29:19 -0700512 if (write(keyboardFd, report, KEY_REPORT_LENGTH) == KEY_REPORT_LENGTH)
Eddie James7cf1f1d2019-09-30 15:05:16 -0500513 {
Zev Weiss40fd5422021-06-17 05:41:40 +0000514 return true;
Eddie James7cf1f1d2019-09-30 15:05:16 -0500515 }
516
Jae Hyun Yoo673ac2e2020-07-30 00:29:19 -0700517 if (errno != EAGAIN)
518 {
519 if (errno != ESHUTDOWN)
520 {
521 log<level::ERR>("Failed to write keyboard report",
522 entry("ERROR=%s", strerror(errno)));
523 }
524
525 break;
526 }
527
528 lk.unlock();
529 std::this_thread::sleep_for(std::chrono::milliseconds(10));
530 lk.lock();
531 retryCount--;
532 }
533
Zev Weiss40fd5422021-06-17 05:41:40 +0000534 return false;
Eddie James7cf1f1d2019-09-30 15:05:16 -0500535}
536
537void Input::writePointer(const uint8_t *report)
538{
Jae Hyun Yoo673ac2e2020-07-30 00:29:19 -0700539 std::unique_lock<std::mutex> lk(ptrMutex);
540 uint retryCount = HID_REPORT_RETRY_MAX;
541
542 while (retryCount > 0)
Eddie James7cf1f1d2019-09-30 15:05:16 -0500543 {
Jae Hyun Yoo673ac2e2020-07-30 00:29:19 -0700544 if (write(pointerFd, report, PTR_REPORT_LENGTH) == PTR_REPORT_LENGTH)
Eddie James7cf1f1d2019-09-30 15:05:16 -0500545 {
Jae Hyun Yoo673ac2e2020-07-30 00:29:19 -0700546 break;
Eddie James7cf1f1d2019-09-30 15:05:16 -0500547 }
Jae Hyun Yoo673ac2e2020-07-30 00:29:19 -0700548
549 if (errno != EAGAIN)
550 {
551 if (errno != ESHUTDOWN)
552 {
553 log<level::ERR>("Failed to write pointer report",
554 entry("ERROR=%s", strerror(errno)));
555 }
556
557 break;
558 }
559
560 lk.unlock();
561 std::this_thread::sleep_for(std::chrono::milliseconds(10));
562 lk.lock();
563 retryCount--;
Eddie James7cf1f1d2019-09-30 15:05:16 -0500564 }
565}
566
Eddie James21b177e2018-12-11 13:14:46 -0600567} // namespace ikvm