1 #include 2 #include 4 struct termio tsav, tchg; 6 main (argc, argv) 7 { 8 int c; 10 /* change the terminal based on file primitives */ изменить режим терминала с помощью файловых примитивов 11 close(0); 12 if (open("/dev/tty",O_RDWR|O_NDELAY) == -1) { 13 perror("can't open tty"); невозможно открыть tty 14 exit(1); 15 } 17 /* change the terminal based on line disciplines */ изменить режим терминала с помощью протокола работы 18 if (ioctl (0, TCGETA, &tsav) == -1) { 19 perror("can't get original settings"); невозможно получить исходные установки 20 exit(2); 21 } 23 tchg = tsav; 25 tchg.c_lflag &= ~(ICANON | ECHO); 26 tchg.c_cc[VMIN] = 1; 27 tchg.c_cc[VTIME] = 0; 29 if (ioctl (0, TCSETA, &tchg) == -1) { 30 perror(can't initiate new settings"); невозможно задать новые установки 31 } 33 while (1) 34 { 35 putchar('.'); 36 c = getchar(); 38 if (c == 'x') 39 break; 41 putchar(c); 42 } 44 if (ioctl(0, TCSETA, &tsav) == -1) { 45 perror("can't reset original settings"); невозможно вернуть исходные установки 46 exit(3); 47 } 48 }

Основное изменение производится в строках 11-15. Закрытие файла с нулевым дескриптором (который обозначает стандартное устройство ввода) закрывает стандартный ввод. Затем мы снова открываем файл /dev/tty. Значение дескриптора файла равно нулю, так что мы переназначили стандартный ввод на новое устройство. Фокус в том, что при открытии файла используется режим, называемый NODELAY. Это означает, что когда выполняется чтение по данному дескриптору файла (т.е. чтение стандартного ввода), вместо ожидания ввода выполняется просмотр, есть ли там что-нибудь, а затем работа продолжается.

В бесконечном цикле строка 35 печатает точку. Когда вы запускаете эту программу, на экран выводится точка, как только программа попадает в цикл. Если вы ждете, то продолжают выводиться точки. Как только вы нажмете клавишу, выполнится эхо-отображение символа в промежутке между выводом точек. Это демонстрирует, что программа работает в то время, когда вы ничего не делаете.