I am not certain if this is ultimately the correct place to ask this but I am developing a program which requires real-time input from the user. That is; it needs to be able to read the keys being pressed(and optionally held down and released) in real time. What makes this issue a bit troublesome is that I absolutely can not use any kinds of libraries for this; not even the standard C library. So this needs to be handled with raw kernel syscalls and int 0x80.I thought I would set stdin to non-blocking mode with fcntl and O_NONBLOCK and then read the input data from stdin. However, to my surprise my code seems not to be working correctly. Right now it seems that the input gets to be read from stdin after the Enter key is being pressed. The tricky part is that I am finding it troublesome to figure out whether it is the fault of:My code not behaving right(most probable)My terminal/user/process(whatever handles it?) not having non-blocking write access to stdin(not probable). Me assuming wrongly that I can read direct keyboard input from stdin.So my question is that what is the best/usual way of reading direct keyboard interaction if not by setting the stdin to non-blocking mode and reading the keyboard input data from there? Or am I correct and should just fix my code? :)(And for the curious, no, it's not a keylogger. It is for a very size limited(executable size <= 256 bytes) demoscene product which requires user to be able to ESC out from the intro.)
How to directly read keyboard input in real-time?
c;input
If you're going to be reading from stdin, you should read the manpage for tcsetattr, and specifically the section about Canonical and noncanonical mode (ICANON). Unless you disable ICANON on stdin, input is line-oriented (you get nothing until Enter is pressed). That's the case even for O_NONBLOCK.If in doubt, strace -v stty raw >&log; stty sane; grep TCSETSW logand see what it does to stdin. You can use the same system call with identical parameters to uncook the terminal. Be careful, unless you restore the settings on exit, the terminal will be useless after your program terminates. (this is why I did stty sane after stty raw)Using raw hardware I/O is probably a very bad idea, unless you're absolutely certain about your target hardware, and/or you want to anticipate every type of keyboard there is.Oh, despite it being raw, you're still reading somewhat cooked input from the keyboard: you won't get scancodes, you'll get ASCII (or UTF-8, most likely). So Escape is decimal 27, not 1 (as on the original IBM PC keyboard).Alternative suggestion that requires superuser access: read up on event devices, open the right one and read Linux event structures from it. This method returns raw press/release events and key (they're the kernel's internal key codes, though, not hardware scancodes). Check out /usr/include/linux/input.h for the specifics. Finding the right eventX device to open in 256 bytes of code is another matter altogether, of course.