I have a piece of code in which I want to read a character from the terminal. The goal is to give keyboard input for moving a robot.
If there is no input in the terminal , the code should return -1, which it does, but even when I do give inputs, it always returns -1 with errno set to EAGAIN. According to the documentation, it means: no data available. Does anyone has an idea why is that happening?
Here is the code, reduced to a minimal version:
#include <termios.h>
#include <cstdio>
int getch()
{
int ch;
struct termios oldt;
struct termios newt;
// Store old settings, and copy to new settings
tcgetattr(0, &oldt);
newt = oldt;
// Make required changes and apply the settings
newt.c_lflag &= ~(ICANON | ECHO);
newt.c_iflag |= IGNBRK;
newt.c_iflag &= ~(INLCR | ICRNL | IXON | IXOFF);
newt.c_lflag &= ~(ICANON | ECHO | ECHOK | ECHOE | ECHONL | ISIG | IEXTEN);
newt.c_cc[VMIN] = 0;
newt.c_cc[VTIME] = 1;
tcsetattr(fileno(stdin), TCSANOW, &newt);
// Get the current character
ch = getchar();
// Reapply old settings
tcsetattr(0, TCSANOW, &oldt);
return ch;
}
int main(int argc, char **argv)
{
long count = 0;
while (true)
{
int ch = 0;
ch = getch();
printf("%ld\n", count++);
printf("char = %d\n\n", ch);
switch (ch)
{
case 'q':
printf("already quit!\n");
return 0;
case 'w':
printf("move forward!\n");
break;
case 's':
printf("move backward!\n");
break;
case 'a':
printf("move left!\n");
break;
case 'd':
printf("move right!\n");
break;
case 'j':
printf("turn left!\n");
break;
case 'l':
printf("turn right!\n");
break;
default:
printf("Stop!\n");
break;
}
}
return 0;
}
I precise that the code works when I change VMIN and VTIME: it can read the inputs from the terminal, but the problem is that then it blocks and if I do not give any input, it doesn't exit, while the expected result is that it outputs -1. I'm on Ubuntu 20.04, using gnome-terminal. Thanks for any help!
What I did, what I expected to happen, what actually happens: I tried to run my code and expected that when I hit a key of my keyboard, it returns the key I pressed, but instead, it always returns -1.