Um kbhit() para o Linux…

No facebook vi uma pergunta a respeito da antiga função kbhit(), que existia nas bibliotecas de certos compiladores C. Perguntaram como essa função poderia ser implementada para Linux.

Essencialmente ela é a mesma que a função getch(), que mostrei no post anterior. A diferença é que o file descriptor STDIN_FILENO deve ser reconfigurado como non blocking:

#include <stdio.h>
#include <termios.h>
#include <unistd.h>
#include <fcntl.h>

int kbhit(void)
{
  struct termios oldt, newt;
  int ch;
  int oldf;
 
  tcgetattr(STDIN_FILENO, &oldt);
  newt = oldt;
  newt.c_lflag &= ~(ICANON | ECHO);
  tcsetattr(STDIN_FILENO, TCSANOW, &newt);

  // Eis a diferença essenaial entre este código e o
  // de getch().
  oldf = fcntl(STDIN_FILENO, F_GETFL, 0);
  fcntl(STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK);
 
  ch = getchar();
 
  tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
  fcntl(STDIN_FILENO, F_SETFL, oldf);
 
  // Se getchar() conseguiu ler uma tecla,
  // a deveolve para STDIN...
  if (ch != EOF)
  {
    ungetc(ch, stdin);
    return 1;
  }
 
  return 0;
}
Anúncios

Deixe um comentário

Faça o login usando um destes métodos para comentar:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s