Das war mal ne Uebungsaufgabe zu dem Thema.
Sollte als Grundlage (mit passendem man-page Studium) reichen. Viel Spass damit ;-)
Code:
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <termios.h>
#include <errno.h>
/* define keycodes according to extended ASCII */
#define ASCII_ESC 27
#define ASCII_CTRL_E 5
#define ASCII_CTRL_N 14
/* shortcut for simple system/library-call error checking */
#define ERROR_CHECK(error_condition)\
if (error_condition){\
perror("type");\
exit(EXIT_FAILURE);\
}
/* terminal modes */
struct termios oldmode;
struct termios newmode;
/* restore previous terminal mode */
void cleanup(){
tcsetattr(STDIN_FILENO,TCSAFLUSH,&oldmode);
}
/* someone has to do the main work :-) */
int main(int argc,char * argv[]){
char ch;
int loop;
int tty=0;
/* do we have a terminal to manipulate? */
if (isatty(STDIN_FILENO)==1){
/* save old mode */
ERROR_CHECK((tcgetattr(STDIN_FILENO,&oldmode)<0)||(tcgetattr(STDIN_FILENO,&newmode)<0));
/* install cleanup function */
ERROR_CHECK(atexit(cleanup)<0);
/* set noncanonical,signal ignoring,one char returning terminal mode */
newmode.c_lflag &= ~(ICANON|ISIG);
newmode.c_cc[VMIN] = 1;
newmode.c_cc[VTIME] = 0;
ERROR_CHECK(tcsetattr(STDIN_FILENO,TCSAFLUSH,&newmode)<0);
tty=1;
}
/* while escaped has not been typed */
for (loop=1;loop;){
/* read a single character */
while (read(STDIN_FILENO,&ch,1)<0) ERROR_CHECK(errno!=EINTR);
switch (ch){
case ASCII_ESC: /* exit */
loop=0;
break;
case ASCII_CTRL_N: /* turn off echo */
if (!tty) break;
newmode.c_lflag &= ~ECHO;
ERROR_CHECK(tcsetattr(STDIN_FILENO,TCSAFLUSH,&newmode)<0);
break;
case ASCII_CTRL_E: /* turn on echo */
if (!tty) break;
newmode.c_lflag |= ECHO;
ERROR_CHECK(tcsetattr(STDIN_FILENO,TCSAFLUSH,&newmode)<0);
break;
default: /* own echo on stdout */
while (write(STDOUT_FILENO,&ch,1)<0) ERROR_CHECK(errno!=EINTR);
}
return EXIT_SUCCESS;
}
Lesezeichen