在原始模式下,转义序列与查找光标位置和`stdin()`之间的干扰

时间:2018-01-22 06:30:14

标签: c stdin cursor-position termios

我在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()锁定文件访问权限,或通过修改波特率来分离这两个输入,但都无济于事。

我确信有一种简单的方法可以做到这一点,我在某处感到困惑,但我似乎无法找到。

0 个答案:

没有答案