If it's a small project for educational purpose you can try to look at tcgetattr
(man page is very descriptive).
This is an example of proper configuration:
#include <termios.h>
#include <unistd.h>
struct termios old_term;
void set_new_term() {
struct termios new_term;
tcgetattr(STDIN_FILENO, &old_term);
tcgetattr(STDIN_FILENO, &new_term);
new_term.c_lflag &= (~ICANON & ~ECHO);
new_term.c_cc[VMIN] = 0;
new_term.c_cc[VTIME] = 0;
tcsetattr(STDIN_FILENO, TCSAFLUSH, &new_term);
}
And don't forget to restore old terminal settings before exit (with tcsetattr(STDIN_FILENO, TCSANOW, &old_term)
)
So the idea is to set noncanonical mode.
In noncanonical mode input is available immediately (without the user
having to type a line-delimiter character), no input processing is
performed, and line editing is disabled.
And now, when you're done with terminal, you need to track all strings of the form
str[0] = '\x1b'
str[1] = '['
str[2] = 'A' or 'B' or 'C' or 'D' /* A - for up
B - down
C - right
D - left */
But once again all this is useful only if you want to have fun, but in general I think readline is a good solution. There is even rlwrap
available on ubuntu.
rlwrap runs the specified command, intercepting user input in order to
provide readline's line editing, persistent history and completion.
So you can run:
$> rlwrap your_program_name