0

I am writing a shell emulator in C, and put the terminal in raw mode. To get the cursor position and move using termcaps when necessary, I printed the escape sequence \033[6n and parsed its return.

The problem is that a high input rate (when I basically hit my keyboard), my input messes up with getting the return of the escape sequence, and ; characters appear on my screen.

This is how I parsed the return of the escape sequence :

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;
}

This is the function read_cursor I called several times :

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;
    }
}

And finally this is how I began by setting the terminal and raw-mode to have a non-blocking read() :

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;
 }

I tried separating those two inputs by writing on the file stream, or by trying to lock the file access with fcntl(), or by modifying the baud rate, all to no avail.

I'm sure there is an easy way to do this and that I am confused somewhere, but I can't seem to find.

Thomas Dickey
  • 51,086
  • 7
  • 70
  • 105

0 Answers0