Skip to content

Instantly share code, notes, and snippets.

@whyrusleeping
Created October 30, 2012 21:49
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save whyrusleeping/3983293 to your computer and use it in GitHub Desktop.
Save whyrusleeping/3983293 to your computer and use it in GitHub Desktop.
Non Blocking Keyboard Input (C++)
#include <termios.h>
#include <stdlib.h>
void RestoreKeyboardBlocking(struct termios *initial_settings)
{
tcsetattr(0, TCSANOW, initial_settings);
}
void SetKeyboardNonBlock(struct termios *initial_settings)
{
struct termios new_settings;
tcgetattr(0,initial_settings);
new_settings = initial_settings;
new_settings.c_lflag &= ~ICANON;
new_settings.c_lflag &= ~ECHO;
new_settings.c_lflag &= ~ISIG;
new_settings.c_cc[VMIN] = 0;
new_settings.c_cc[VTIME] = 0;
tcsetattr(0, TCSANOW, &new_settings);
}
int main()
{
struct termios term_settings;
char c = 0;
SetKeyboardNonBlock(&term_settings);
while(c != 'Q')
{
c = getchar();
if(c > 0)
printf("Read: %c\n", c);
}
//Not restoring the keyboard settings causes the input from the terminal to not work right
RestoreKeyboardBlocking(&term_settings);
return 0;
}
@neilyoung
Copy link

Doesn't work

@alephnul
Copy link

Doesn't work

can you let everyone know why? or what exactly does not work in your case?

@Sonander
Copy link

Thanks for this. I was struggling to get non blocking getchar going until I found this which got me reading the c_cc[VMIN] and c_cc[VTIME] in the termios docs. Here are the extra steps I had to take to get a working solution:

Line 15, change to
new_settings = *initial_settings;
to avoid compiler error

error: no match for 'operator=' (operand types are 'termios' and 'termios*')

That got it to compile and I notice getchar isn't blocking now, which is good, but with just two small problems. getchar always returns EOF and doesn't pull any characters from the input buffer :-)

The termios documentation doesn't mention getchar, it talks about its affect on read() so I replaced getchar with

char getcharAlt() {
    char buff[2];
    int l = read(STDIN_FILENO,buff,1);
    if (l>0) return buff[0];
    return ( EOF);
}

and have a solution for my Raspberry Pi running Raspbian Buster.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment