Skip to content

Instantly share code, notes, and snippets.

@mildsunrise
Last active October 22, 2015 11:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mildsunrise/d55bfb52f8b5b5fe01e4 to your computer and use it in GitHub Desktop.
Save mildsunrise/d55bfb52f8b5b5fe01e4 to your computer and use it in GitHub Desktop.
VMIN=0 + select(), possible kernel bug?
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/select.h>
int main() {
// 1. Retrieve current terminal attributes
struct termios orig_attributes, attributes;
assert(tcgetattr(0, &attributes) == 0);
orig_attributes = attributes;
// 2. Remove ICANON and ECHO, set VMIN and VTIME to zero
attributes.c_cc[VMIN] = 0;
attributes.c_cc[VTIME] = 0;
attributes.c_lflag &= ~(ICANON|ECHO);
assert(tcsetattr(0, TCSANOW, &attributes) == 0);
// 3. Wait for stdin to have input
fd_set set; FD_ZERO(&set); FD_SET(0, &set);
assert(select(1, &set, NULL, NULL, NULL) == 1);
// 4. Read it from stdin
char buf [10];
printf("Read returned: %d\n", read(0, buf, 10));
tcsetattr(0, TCSANOW, &orig_attributes);
return 0;
}

This is a pretty simple program, which only consists of four syscalls.
On most Linuxes I've tested, this program waits for you to press a key, and then prints:

Read returned: 1

However, on some Linux installs, starting the program will immediately print:

Read returned: 0

And exit.

See the original StackOverflow question for more info. This was discovered by investigating mplayer2 key handling code.

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