Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

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.


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: