#include "libbb.h" static struct termios dummy = { 0, /* c_iflag */ 0, /* c_oflag */ 0, /* c_cflag */ 0, /* c_lflag */ '\0', /* c_line */ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", /* c_cc[NCCS] */ B9600, /* c_ispeed */ B9600 /* c_ospeed */ }; int tcsetattr(int fd UNUSED_PARAM, int mode UNUSED_PARAM, const struct termios *t) { dummy = *t; return 0; } int tcgetattr(int fd UNUSED_PARAM, struct termios *t) { *t = dummy; return 0; } int64_t FAST_FUNC read_key(int fd, char *buf UNUSED_PARAM, int timeout) { HANDLE cin = GetStdHandle(STD_INPUT_HANDLE); INPUT_RECORD record; DWORD nevent_out, mode; int ret = -1; char *s; if (fd != 0) bb_error_msg_and_die("read_key only works on stdin"); if (cin == INVALID_HANDLE_VALUE) return -1; GetConsoleMode(cin, &mode); SetConsoleMode(cin, 0); if (timeout > 0) { if (WaitForSingleObject(cin, timeout) != WAIT_OBJECT_0) goto done; } while (1) { if (!ReadConsoleInput(cin, &record, 1, &nevent_out)) goto done; if (record.EventType != KEY_EVENT || !record.Event.KeyEvent.bKeyDown) continue; if (!record.Event.KeyEvent.uChar.AsciiChar) { DWORD state = record.Event.KeyEvent.dwControlKeyState; if (state & (RIGHT_CTRL_PRESSED|LEFT_CTRL_PRESSED) && (record.Event.KeyEvent.wVirtualKeyCode >= 'A' && record.Event.KeyEvent.wVirtualKeyCode <= 'Z')) { ret = record.Event.KeyEvent.wVirtualKeyCode & ~0x40; break; } switch (record.Event.KeyEvent.wVirtualKeyCode) { case VK_DELETE: ret = KEYCODE_DELETE; goto done; case VK_INSERT: ret = KEYCODE_INSERT; goto done; case VK_UP: ret = KEYCODE_UP; goto done; case VK_DOWN: ret = KEYCODE_DOWN; goto done; case VK_RIGHT: if (state & (RIGHT_CTRL_PRESSED|LEFT_CTRL_PRESSED)) { ret = KEYCODE_CTRL_RIGHT; goto done; } ret = KEYCODE_RIGHT; goto done; case VK_LEFT: if (state & (RIGHT_CTRL_PRESSED|LEFT_CTRL_PRESSED)) { ret = KEYCODE_CTRL_LEFT; goto done; } ret = KEYCODE_LEFT; goto done; case VK_HOME: ret = KEYCODE_HOME; goto done; case VK_END: ret = KEYCODE_END; goto done; case VK_PRIOR: ret = KEYCODE_PAGEUP; goto done; case VK_NEXT: ret = KEYCODE_PAGEDOWN; goto done; } continue; } if ( (record.Event.KeyEvent.uChar.AsciiChar & 0x80) == 0x80 ) { s = &record.Event.KeyEvent.uChar.AsciiChar; OemToCharBuff(s, s, 1); } ret = record.Event.KeyEvent.uChar.AsciiChar; break; } done: SetConsoleMode(cin, mode); return ret; } speed_t cfgetispeed(const struct termios *termios_p) { return termios_p->c_ispeed; } speed_t cfgetospeed(const struct termios *termios_p) { return termios_p->c_ospeed; } int cfsetispeed(struct termios *termios_p, speed_t speed) { termios_p->c_ispeed = speed; return 0; } int cfsetospeed(struct termios *termios_p, speed_t speed) { termios_p->c_ospeed = speed; return 0; }