Created
November 15, 2021 13:00
-
-
Save emandret/9ad3066e10523c80804d3345b91adcc2 to your computer and use it in GitHub Desktop.
Compare the canonical vs. noncanonical input modes of the TTY line driver
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <termios.h> | |
#include <unistd.h> | |
#define MAX_BUFSIZE 4096 | |
int main(int argc, char *argv[]) | |
{ | |
struct termios old_termios; | |
struct termios new_termios; | |
char *tty_devfile; | |
char buf[MAX_BUFSIZE]; | |
int bytes_read; | |
if ( argc < 2 ) { | |
dprintf(2, "Pass argument 1 for canonical mode, 0 for noncanonical\n"); | |
return 1; | |
} | |
if ( !isatty(0) ) { | |
dprintf(2, "STDIN is not a terminal device\n"); | |
return 1; | |
} | |
if ( (tty_devfile = ttyname(0)) ) { | |
dprintf(2, "Using terminal device %s\n", tty_devfile); | |
} | |
if ( tcgetattr(0, &old_termios) == -1 ) { | |
perror("Error while getting old terminal settings"); | |
return 1; | |
} | |
new_termios = old_termios; | |
switch ( argv[1][0] ) { | |
case '0': | |
// If MIN > 0 then a pending read is not satisfied until MIN bytes are received. A program that uses this case | |
// to read record-based terminal I/O may block indefinitely in the read operation. If MIN = 0 and no characters | |
// are available, read is nonblocking and returns a value of zero, having read no data. | |
new_termios.c_lflag &= ~(ICANON | ECHO); | |
new_termios.c_cc[VMIN] = 0; | |
new_termios.c_cc[VTIME] = 0; | |
break; | |
case '1': | |
new_termios.c_lflag &= ICANON | ECHO | ECHOE; | |
new_termios.c_cc[VMIN] = 0; | |
new_termios.c_cc[VTIME] = 0; | |
break; | |
default: | |
dprintf(2, "Invalid argument\n"); | |
return 1; | |
} | |
if ( tcsetattr(0, TCSADRAIN, &new_termios) == -1 ) { | |
perror("Error while setting new terminal settings"); | |
return 1; | |
} | |
while ( (bytes_read = read(0, buf, sizeof(buf) - 1)) != -1 ) { | |
if ( bytes_read > 0 ) { | |
buf[bytes_read] = '\0'; | |
if ( buf[0] == 'q' ) { | |
dprintf(2, "Exiting...\n"); | |
break; | |
} | |
dprintf(2, "Bytes read: %d\n", bytes_read); | |
dprintf(2, "Buffer content: %s\n", buf); | |
} | |
} | |
if ( tcsetattr(0, TCSADRAIN, &old_termios) == -1 ) { | |
perror("Error while resetting old terminal settings"); | |
return 1; | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment