5

CODE

while (1)
    {
        keycode = key_hook();
        if (keycode == SPACE || keycode == BKSPACE)
        {
            render_again = 1;
        }
        if (keycode == ESC)
            break;
        if (render_again)
        {
            render_again = 0;
            render(all);
        }
        dprintf(1, "");      //I have no idea why this prevents the program from freezing
    }
    int key_hook()
    {
     char buffer[4];

     read(0, buffer, 4);
     return (*(unsigned int *)buffer);
    }

Alright, so this piece of code handles redrawing of text on screen. Some rows of text are underlined or highlighted using termcaps (tputs(tgetstr("us, NULL")......). Everything prints fine but after the first redraw of the text the while apparently freezes unless a dprintf/printf is present. The key_hook function just reads 4 bytes from the stdin and converts them to an int.

Box Box Box Box
  • 5,094
  • 10
  • 49
  • 67
Rpreda
  • 147
  • 1
  • 7
  • Post `key_hook` function could be a good idea... – LPs Jan 14 '16 at 08:20
  • How do 4 characters from stdin equate to a key press? I assume this program isn't reading from a tty? – trojanfoe Jan 14 '16 at 08:31
  • It is but i need 4 characters for special keys like the arrow keys for example which are code like this ^[[C – Rpreda Jan 14 '16 at 08:34
  • 1
    Not sure I follow. I thought that `^[` was a visual representation of `ESC`... – trojanfoe Jan 14 '16 at 08:39
  • Well the arrow keys are comprised of 4 characters when read from a terminal, that's what I deducted from testing, it works fine until I introduced the termcaps part which freezes it – Rpreda Jan 14 '16 at 08:43
  • I'm completely guessing. It smell like `dfrintf` flushes your `stdin` in someway. Are you sure that the program freeze? Could be that `key_hook` `read` function return constantly a value? Did you try to debug it putting a breakpoint in the first `if`? – LPs Jan 14 '16 at 08:44
  • @trojanfoe Is right, `^[` is a visual representation of `ESC`. Actually, `^[[C` returns 3 characters `^[` (`0x1b` - `ESC`), `[` and `C`, but you probably get a fourth character which is `\n`. – Holt Jan 14 '16 at 08:45
  • The program is indeed freezing, I tried with the debugger and also I opened a file where I write the output of the key_hook function. After writing with termcaps the writing in the file stops. Not only printf unlocks it, an empty write seems to also do the trick. – Rpreda Jan 14 '16 at 09:16
  • What happens when you pass a value smaller than 4 to `read`? Such as 2 and then type something like `q` followed by return? – Samir Aguiar Jan 14 '16 at 10:05
  • Also, check the return value of `read` and `errno` – Samir Aguiar Jan 14 '16 at 10:08
  • When I write less than 4 characters it just reads it straight away, it doesn't way for enter probably because the terminal is in raw mode. (ICANON flag removed). While using the debugger the program doesn't read the right thing, buffer always seems to end with \x7f, but when I use it out of the debugger and write an empt string first it works. – Rpreda Jan 14 '16 at 11:20
  • you need to put the keyboard into 'scan' mode, using the information found at: (which is several pages long) Which also shows how to read the scan mode keystrokes and how to exit scan mode. Note, this needs to be performed from inside a program as the normal usage of the keys is not available. Note: some keys will produce a string of (up to) 6 characters, like the `pause` key – user3629249 Jan 15 '16 at 19:38

1 Answers1

1

When I last did work here, my version of key_hook had a loop of single byte reads. This was broken by an alarm of 1 second and logic to whether the data so far was a key prefix.

The alarm interrupted the read, and stopped freeze

mksteve
  • 12,614
  • 3
  • 28
  • 50