cunixiogetcharposix-select

Strange C behavior occured when getting multiple characters from an nonblocking IO using getchar() and select()


I'm doing some experience on unix nonblocking IO programming. I put a select() and getchar() function in an infinite loop, expecting that if I input multiple characters to stdin and press enter, all of this characters will be printed out one by one by printf(). However, it is just the first character I input was printed, other characters not printed until I input characters again.

Here is my code:

int main () {
  fd_set readFdSet;
  struct timeval timeout;
  int selectResult;
  char c;
  while(1) {
    FD_ZERO(&readFdSet);
    FD_SET(fileno(stdin), &readFdSet);
    timeout.tv_sec = 0;
    timeout.tv_usec = 0;
    selectResult = select(fileno(stdin)+1, &readFdSet,
                           NULL, NULL, &timeout);

    if (FD_ISSET(fileno(stdin), &readFdSet)) {
      c = getchar();
      printf("getchar: %c\n", c);
    } 
  }
}

The result is:

-->input  abcd\n
-->output getchar: a
-->input  abcd\n
-->output getchar: b
-->output getchar: c
-->output getchar: d
-->output getchar: '\n'
-->output getchar: a

Solution

  • This is probably because you are mixing buffered and unbuffered standard input functions. Select is supposed to be used in combination with read and write. In your case replace c = getchar(); by the following.

    read(fileno(stdin), &c, 1);
    

    Also note that fileno(stdin) is better to be referred as STDIN_FILENO.