#include <termios.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
/* Legge un sigolo carattere dal terminale senza
* aspettare la pressione del tasto invio.
* Restituisce 1 in caso di successo, 0 in caso di errore.
* Il carattere letto viene memorizzato nel parametro `c' */
unsigned char read_nocannon(int *c)
{
/* orig per ripristinare le impostazioni
* new per cambiare le impostazioni */
struct termios orig, new;
/* Legge le impostazioni del terminale e
* le memorizza in orig (vedere `man tcgetattr')*/
if(tcgetattr(0, &orig) != 0)
{
perror("tcgetattr");
return 0;
}
/* copia le impostazioni in new. Metodo consigliato nella
* documentazione della libreria GNU C (vedere `info libc') */
memcpy(&new, &orig, sizeof(struct termios));
/* Imposta `canonical imput' e toglie l'echo dei caratteri */
new.c_lflag &= ~(ICANON|ECHO);
/* Imposta il minimo numero di caratteri da leggere */
new.c_cc[VMIN] = 1;
/* Imposta il tempo di attesa 0 dice a read di attendere finchè non ci
* sono X.c_cc[VMIN] caratteri letti */
new.c_cc[VTIME] = 0;
/* Setta le nuove impostazioni (vedere `man tcsetattr') */
if(tcsetattr(0, TCSANOW, &new) != 0)
{
perror("tcsetattr");
return 0;
}
/* legge 1 carattere */
if(read(0, c, 1) == -1)
{
perror("read");
tcsetattr(0, TCSANOW, &orig);
return 0;
}
/* Ripristina le impostazioni precedenti ###IMPORTANTE### */
tcsetattr(0, TCSANOW, &orig);
return 1;
}
int main()
{
int c;
if(read_nocannon(&c))
{
printf("Read one character: '%c'\n", c);
return EXIT_SUCCESS;
}
return EXIT_FAILURE;
}