I recently wanted to give a command-line program the ability to wait for and respond to keypresses instantly, without the user having to type Enter. It sounded simple enough. Here's what you have to do to set this up:
// headers for terminal control
#include <termios.h>
#include <unistd.h>
// global variable
struct termios saved_attributes;
// prototype of atexit callback
void reset_input_mode (void);
// --- inside main()
// local variable
struct termios termios_data;
// tell stdio not to buffer output
setvbuf(stdout, NULL, _IONBF, 0);
// incantation to the terminal
tcgetattr(0, &termios_data);
saved_attributes = termios_data;
termios_data.c_lflag &= ~(ECHO | ECHONL | ICANON | IEXTEN);
termios_data.c_cc[VMIN] = 1;
tcsetattr(0, TCSANOW, &termios_data);
// set atexit callback so we can restore the prior terminal mode upon exit
atexit(reset_input_mode);
// --- outside main()
// implementation of atexit callback -- restores terminal to prior mode
void reset_input_mode (void)
{
tcsetattr (STDIN_FILENO, TCSANOW, &saved_attributes);
}
Now, you can read input one byte at a time (with, e.g. getchar(3)) and output appears instantly.