blob: 480db3c094bce4139a4f6c759c58531f321a8007 [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
Jae Hyun Yoo33890982019-03-19 10:20:27 -0700216 input->pointerReport[0] = ((buttonMask & 0x4) >> 1) |
217 ((buttonMask & 0x2) << 1) | (buttonMask & 0x1);
Eddie James21b177e2018-12-11 13:14:46 -0600218
219 if (x >= 0 && (unsigned int)x < video.getWidth())
220 {
Jae Hyun Yoo2bc661d2019-02-25 13:52:47 -0800221 uint16_t xx = (uint16_t)(x * (SHRT_MAX + 1) / video.getWidth());
Eddie James21b177e2018-12-11 13:14:46 -0600222
Jae Hyun Yoo7dfac9f2019-01-15 10:14:59 -0800223 memcpy(&input->pointerReport[1], &xx, 2);
Eddie James21b177e2018-12-11 13:14:46 -0600224 }
225
226 if (y >= 0 && (unsigned int)y < video.getHeight())
227 {
Jae Hyun Yoo2bc661d2019-02-25 13:52:47 -0800228 uint16_t yy = (uint16_t)(y * (SHRT_MAX + 1) / video.getHeight());
Eddie James21b177e2018-12-11 13:14:46 -0600229
Jae Hyun Yoo7dfac9f2019-01-15 10:14:59 -0800230 memcpy(&input->pointerReport[3], &yy, 2);
Eddie James21b177e2018-12-11 13:14:46 -0600231 }
232
Eddie James21b177e2018-12-11 13:14:46 -0600233 rfbDefaultPtrAddEvent(buttonMask, x, y, cl);
Jae Hyun Yoo673ac2e2020-07-30 00:29:19 -0700234 input->writePointer(input->pointerReport);
Eddie James21b177e2018-12-11 13:14:46 -0600235}
236
Jae Hyun Yoo7dfac9f2019-01-15 10:14:59 -0800237void Input::sendWakeupPacket()
Eddie James21b177e2018-12-11 13:14:46 -0600238{
Jae Hyun Yooeaf5c5b2019-02-20 15:03:17 -0800239 uint8_t wakeupReport[KEY_REPORT_LENGTH] = {0};
Jae Hyun Yoo7dfac9f2019-01-15 10:14:59 -0800240
Jae Hyun Yooeaf5c5b2019-02-20 15:03:17 -0800241 if (pointerFd >= 0)
Jae Hyun Yoo7dfac9f2019-01-15 10:14:59 -0800242 {
Jae Hyun Yooeaf5c5b2019-02-20 15:03:17 -0800243 uint16_t xy = SHRT_MAX / 2;
244
245 memcpy(&wakeupReport[1], &xy, 2);
246 memcpy(&wakeupReport[3], &xy, 2);
247
Eddie James7cf1f1d2019-09-30 15:05:16 -0500248 writePointer(wakeupReport);
Jae Hyun Yoo7dfac9f2019-01-15 10:14:59 -0800249 }
250
Jae Hyun Yooeaf5c5b2019-02-20 15:03:17 -0800251 if (keyboardFd >= 0)
Eddie James21b177e2018-12-11 13:14:46 -0600252 {
Jae Hyun Yooeaf5c5b2019-02-20 15:03:17 -0800253 memset(&wakeupReport[0], 0, KEY_REPORT_LENGTH);
254
255 wakeupReport[0] = keyToMod(XK_Shift_L);
256
Eddie James7cf1f1d2019-09-30 15:05:16 -0500257 if (!writeKeyboard(wakeupReport))
Jae Hyun Yooeaf5c5b2019-02-20 15:03:17 -0800258 {
Jae Hyun Yooeaf5c5b2019-02-20 15:03:17 -0800259 return;
260 }
261
262 wakeupReport[0] = 0;
263
Eddie James7cf1f1d2019-09-30 15:05:16 -0500264 writeKeyboard(wakeupReport);
Eddie James21b177e2018-12-11 13:14:46 -0600265 }
266}
267
Jae Hyun Yoo7dfac9f2019-01-15 10:14:59 -0800268uint8_t Input::keyToMod(rfbKeySym key)
Eddie James21b177e2018-12-11 13:14:46 -0600269{
Jae Hyun Yoo7dfac9f2019-01-15 10:14:59 -0800270 uint8_t mod = 0;
Eddie James21b177e2018-12-11 13:14:46 -0600271
272 if (key >= XK_Shift_L && key <= XK_Control_R)
273 {
274 mod = shiftCtrlMap[key - XK_Shift_L];
275 }
276 else if (key >= XK_Meta_L && key <= XK_Alt_R)
277 {
278 mod = metaAltMap[key - XK_Meta_L];
279 }
280
281 return mod;
282}
283
Jae Hyun Yoo7dfac9f2019-01-15 10:14:59 -0800284uint8_t Input::keyToScancode(rfbKeySym key)
Eddie James21b177e2018-12-11 13:14:46 -0600285{
Jae Hyun Yoo7dfac9f2019-01-15 10:14:59 -0800286 uint8_t scancode = 0;
Eddie James21b177e2018-12-11 13:14:46 -0600287
288 if ((key >= 'A' && key <= 'Z') || (key >= 'a' && key <= 'z'))
289 {
290 scancode = USBHID_KEY_A + ((key & 0x5F) - 'A');
291 }
292 else if (key >= '1' && key <= '9')
293 {
294 scancode = USBHID_KEY_1 + (key - '1');
295 }
296 else if (key >= XK_F1 && key <= XK_F12)
297 {
298 scancode = USBHID_KEY_F1 + (key - XK_F1);
299 }
Jae Hyun Yoo513d95e2019-08-20 11:26:53 -0700300 else if (key >= XK_KP_F1 && key <= XK_KP_F4)
301 {
302 scancode = USBHID_KEY_F1 + (key - XK_KP_F1);
303 }
304 else if (key >= XK_KP_1 && key <= XK_KP_9)
305 {
306 scancode = USBHID_KEY_KP_1 + (key - XK_KP_1);
307 }
Eddie James21b177e2018-12-11 13:14:46 -0600308 else
309 {
310 switch (key)
311 {
312 case XK_exclam:
313 scancode = USBHID_KEY_1;
314 break;
315 case XK_at:
316 scancode = USBHID_KEY_2;
317 break;
318 case XK_numbersign:
319 scancode = USBHID_KEY_3;
320 break;
321 case XK_dollar:
322 scancode = USBHID_KEY_4;
323 break;
324 case XK_percent:
325 scancode = USBHID_KEY_5;
326 break;
327 case XK_asciicircum:
328 scancode = USBHID_KEY_6;
329 break;
330 case XK_ampersand:
331 scancode = USBHID_KEY_7;
332 break;
333 case XK_asterisk:
334 scancode = USBHID_KEY_8;
335 break;
336 case XK_parenleft:
337 scancode = USBHID_KEY_9;
338 break;
339 case XK_0:
340 case XK_parenright:
341 scancode = USBHID_KEY_0;
342 break;
343 case XK_Return:
344 scancode = USBHID_KEY_RETURN;
345 break;
346 case XK_Escape:
347 scancode = USBHID_KEY_ESC;
348 break;
349 case XK_BackSpace:
350 scancode = USBHID_KEY_BACKSPACE;
351 break;
352 case XK_Tab:
Jae Hyun Yoo513d95e2019-08-20 11:26:53 -0700353 case XK_KP_Tab:
Eddie James21b177e2018-12-11 13:14:46 -0600354 scancode = USBHID_KEY_TAB;
355 break;
356 case XK_space:
Jae Hyun Yoo513d95e2019-08-20 11:26:53 -0700357 case XK_KP_Space:
Eddie James21b177e2018-12-11 13:14:46 -0600358 scancode = USBHID_KEY_SPACE;
359 break;
360 case XK_minus:
361 case XK_underscore:
362 scancode = USBHID_KEY_MINUS;
363 break;
364 case XK_plus:
365 case XK_equal:
366 scancode = USBHID_KEY_EQUAL;
367 break;
368 case XK_bracketleft:
369 case XK_braceleft:
370 scancode = USBHID_KEY_LEFTBRACE;
371 break;
372 case XK_bracketright:
373 case XK_braceright:
374 scancode = USBHID_KEY_RIGHTBRACE;
375 break;
376 case XK_backslash:
377 case XK_bar:
378 scancode = USBHID_KEY_BACKSLASH;
379 break;
380 case XK_colon:
381 case XK_semicolon:
382 scancode = USBHID_KEY_SEMICOLON;
383 break;
384 case XK_quotedbl:
385 case XK_apostrophe:
386 scancode = USBHID_KEY_APOSTROPHE;
387 break;
388 case XK_grave:
389 case XK_asciitilde:
390 scancode = USBHID_KEY_GRAVE;
391 break;
392 case XK_comma:
393 case XK_less:
394 scancode = USBHID_KEY_COMMA;
395 break;
396 case XK_period:
397 case XK_greater:
398 scancode = USBHID_KEY_DOT;
399 break;
400 case XK_slash:
401 case XK_question:
402 scancode = USBHID_KEY_SLASH;
403 break;
404 case XK_Caps_Lock:
405 scancode = USBHID_KEY_CAPSLOCK;
406 break;
407 case XK_Print:
408 scancode = USBHID_KEY_PRINT;
409 break;
410 case XK_Scroll_Lock:
411 scancode = USBHID_KEY_SCROLLLOCK;
412 break;
413 case XK_Pause:
414 scancode = USBHID_KEY_PAUSE;
415 break;
416 case XK_Insert:
Jae Hyun Yoo513d95e2019-08-20 11:26:53 -0700417 case XK_KP_Insert:
Eddie James21b177e2018-12-11 13:14:46 -0600418 scancode = USBHID_KEY_INSERT;
419 break;
420 case XK_Home:
Jae Hyun Yoo513d95e2019-08-20 11:26:53 -0700421 case XK_KP_Home:
Eddie James21b177e2018-12-11 13:14:46 -0600422 scancode = USBHID_KEY_HOME;
423 break;
424 case XK_Page_Up:
Jae Hyun Yoo513d95e2019-08-20 11:26:53 -0700425 case XK_KP_Page_Up:
Eddie James21b177e2018-12-11 13:14:46 -0600426 scancode = USBHID_KEY_PAGEUP;
427 break;
428 case XK_Delete:
Jae Hyun Yoo513d95e2019-08-20 11:26:53 -0700429 case XK_KP_Delete:
Eddie James21b177e2018-12-11 13:14:46 -0600430 scancode = USBHID_KEY_DELETE;
431 break;
432 case XK_End:
Jae Hyun Yoo513d95e2019-08-20 11:26:53 -0700433 case XK_KP_End:
Eddie James21b177e2018-12-11 13:14:46 -0600434 scancode = USBHID_KEY_END;
435 break;
436 case XK_Page_Down:
Jae Hyun Yoo513d95e2019-08-20 11:26:53 -0700437 case XK_KP_Page_Down:
Eddie James21b177e2018-12-11 13:14:46 -0600438 scancode = USBHID_KEY_PAGEDOWN;
439 break;
440 case XK_Right:
Jae Hyun Yoo513d95e2019-08-20 11:26:53 -0700441 case XK_KP_Right:
Eddie James21b177e2018-12-11 13:14:46 -0600442 scancode = USBHID_KEY_RIGHT;
443 break;
444 case XK_Left:
Jae Hyun Yoo513d95e2019-08-20 11:26:53 -0700445 case XK_KP_Left:
Eddie James21b177e2018-12-11 13:14:46 -0600446 scancode = USBHID_KEY_LEFT;
447 break;
448 case XK_Down:
Jae Hyun Yoo513d95e2019-08-20 11:26:53 -0700449 case XK_KP_Down:
Eddie James21b177e2018-12-11 13:14:46 -0600450 scancode = USBHID_KEY_DOWN;
451 break;
452 case XK_Up:
Jae Hyun Yoo513d95e2019-08-20 11:26:53 -0700453 case XK_KP_Up:
Eddie James21b177e2018-12-11 13:14:46 -0600454 scancode = USBHID_KEY_UP;
455 break;
456 case XK_Num_Lock:
457 scancode = USBHID_KEY_NUMLOCK;
458 break;
Jae Hyun Yoo513d95e2019-08-20 11:26:53 -0700459 case XK_KP_Enter:
460 scancode = USBHID_KEY_KP_ENTER;
461 break;
462 case XK_KP_Equal:
463 scancode = USBHID_KEY_KP_EQUAL;
464 break;
465 case XK_KP_Multiply:
466 scancode = USBHID_KEY_KP_MULTIPLY;
467 break;
468 case XK_KP_Add:
469 scancode = USBHID_KEY_KP_ADD;
470 break;
471 case XK_KP_Subtract:
472 scancode = USBHID_KEY_KP_SUBTRACT;
473 break;
474 case XK_KP_Decimal:
475 scancode = USBHID_KEY_KP_DECIMAL;
476 break;
477 case XK_KP_Divide:
478 scancode = USBHID_KEY_KP_DIVIDE;
479 break;
480 case XK_KP_0:
481 scancode = USBHID_KEY_KP_0;
482 break;
Eddie James21b177e2018-12-11 13:14:46 -0600483 }
484 }
485
486 return scancode;
487}
488
Eddie James7cf1f1d2019-09-30 15:05:16 -0500489bool Input::writeKeyboard(const uint8_t *report)
490{
Jae Hyun Yoo673ac2e2020-07-30 00:29:19 -0700491 std::unique_lock<std::mutex> lk(keyMutex);
492 uint retryCount = HID_REPORT_RETRY_MAX;
493
494 while (retryCount > 0)
Eddie James7cf1f1d2019-09-30 15:05:16 -0500495 {
Jae Hyun Yoo673ac2e2020-07-30 00:29:19 -0700496 if (write(keyboardFd, report, KEY_REPORT_LENGTH) == KEY_REPORT_LENGTH)
Eddie James7cf1f1d2019-09-30 15:05:16 -0500497 {
Jae Hyun Yoo673ac2e2020-07-30 00:29:19 -0700498 break;
Eddie James7cf1f1d2019-09-30 15:05:16 -0500499 }
500
Jae Hyun Yoo673ac2e2020-07-30 00:29:19 -0700501 if (errno != EAGAIN)
502 {
503 if (errno != ESHUTDOWN)
504 {
505 log<level::ERR>("Failed to write keyboard report",
506 entry("ERROR=%s", strerror(errno)));
507 }
508
509 break;
510 }
511
512 lk.unlock();
513 std::this_thread::sleep_for(std::chrono::milliseconds(10));
514 lk.lock();
515 retryCount--;
516 }
517
518 if (!retryCount || errno)
519 {
Eddie James7cf1f1d2019-09-30 15:05:16 -0500520 return false;
521 }
522
523 return true;
524}
525
526void Input::writePointer(const uint8_t *report)
527{
Jae Hyun Yoo673ac2e2020-07-30 00:29:19 -0700528 std::unique_lock<std::mutex> lk(ptrMutex);
529 uint retryCount = HID_REPORT_RETRY_MAX;
530
531 while (retryCount > 0)
Eddie James7cf1f1d2019-09-30 15:05:16 -0500532 {
Jae Hyun Yoo673ac2e2020-07-30 00:29:19 -0700533 if (write(pointerFd, report, PTR_REPORT_LENGTH) == PTR_REPORT_LENGTH)
Eddie James7cf1f1d2019-09-30 15:05:16 -0500534 {
Jae Hyun Yoo673ac2e2020-07-30 00:29:19 -0700535 break;
Eddie James7cf1f1d2019-09-30 15:05:16 -0500536 }
Jae Hyun Yoo673ac2e2020-07-30 00:29:19 -0700537
538 if (errno != EAGAIN)
539 {
540 if (errno != ESHUTDOWN)
541 {
542 log<level::ERR>("Failed to write pointer report",
543 entry("ERROR=%s", strerror(errno)));
544 }
545
546 break;
547 }
548
549 lk.unlock();
550 std::this_thread::sleep_for(std::chrono::milliseconds(10));
551 lk.lock();
552 retryCount--;
Eddie James7cf1f1d2019-09-30 15:05:16 -0500553 }
554}
555
Eddie James21b177e2018-12-11 13:14:46 -0600556} // namespace ikvm