我在C中编写shell仿真器,并将终端设置为原始模式。为了获得光标位置并在必要时使用termcaps移动,我打印了转义序列\033[6n
并解析了它的返回。
问题是输入率很高(当我基本上打到我的键盘时),我的输入因退出转义序列而变得混乱,并且我的屏幕上出现了;
个字符。
这是解析转义序列的方法:
static int fillup_cursor_position(int *x, int *y)
{
int result;
result = 0;
if ((result = read_cursor()) != 27)
return 0;
if ((result = read_cursor()) != '[')
return 0;
result = read_cursor();
while (result >= '0' && result <= '9')
{
*y = 10 * *y + result - '0';
result = read_cursor();
}
if (result != ';')
return (0);
result = read_cursor();
while (result >= '0' && result <= '9')
{
*x = 10 * *x + result - '0';
result = read_cursor();
}
if (result != 'R')
return 0;
return 1;
}
这是我多次调用的函数read_cursor:
static int read_cursor(void)
{
char buffer[4];
int n;
n = 0;
while (1)
{
n = read(0, &buffer, 1);
if (n > 0)
return buffer[0];
else
return 0;
}
}
最后,我通过将终端和raw-mode设置为具有非阻塞读取()来开始:
static int set_non_canonical_input(void)
{
struct termios termios_cpy;
if (tcgetattr(0, &termios_cpy) != 0)
return 0;
cfsetispeed(&termios_cpy, B50);
cfsetospeed(&termios_cpy, B50);
termios_cpy.c_cc[VMIN] = 1;
termios_cpy.c_cc[VTIME] = 0;
termios_cpy.c_lflag &= (IGNBRK);
termios_cpy.c_lflag &= (ICANON);
if (tcsetattr(0, TCSANOW, &termios_cpy) != 0)
return 0;
return 1;
}
我尝试通过写入文件流,或尝试使用fcntl()
锁定文件访问权限,或通过修改波特率来分离这两个输入,但都无济于事。
我确信有一种简单的方法可以做到这一点,我在某处感到困惑,但我似乎无法找到。