Sehr Umfangreiche Webseite zum Programmieren in C Perl CGI, Skripting, Linux, Systemprogrammierung Terminal Konsole Terminal Ein/Ausgabe ioctlC C++ C/C++ ANSI C Linux Linuxsystemprogrammierung Linuxsystemprogrammieren Terminal Konsole Terminal Ein/Ausgabe ioctl 6. Terminal E/A
Bevor Sie zur Terminal-Ein/Ausgabe kommen, muss ich Ihnen erst noch erklären, was es mit den Terminals überhaupt auf sich hat.
Terminals sind über serielle Schnittstelle mit Linux-Rechnern verbunden. Um Sie jetzt nicht zu verwirren, wenn Sie eine Konsole verwenden, arbeiten Sie in gleicher Weise, wie mit einer Terminalleitung, auch wenn keine Verbindung über die serielle Schnittstelle vorliegt. Somit ist die Grundlage eines auf dem Bildschirm konfigurierten Terminals gleichwertig zu der über einem externen angeschlossenen Terminals.
Die Ein/Ausgabe eines Terminals, sind in der Grundeinstellung immer Zeilengepuffert. read wird also erst beendet, wenn die ENTER-Taste gedrückt wurde. Drücken Sie stattdessen die Tastenkombination STRG+D, liefert read 0 (EOF) zurück. Dies bedeutet meist, die Beendigung des Programms. Dieses Verhalten kann mit mit O_NONBLOCK mit der Funktion open() oder nachträglich mit der Funktion fcntl() verändern.
Ein Tipp am Rande: Sie können einige gezeigt Möglichkeiten hier auch verwenden um zwei PC's mit einem Nullmodemkabel zu koppeln. Ein Nullmodemkabel können Sie an der seriellen Schnittstelle des jeweiligen PC's anhängen. Das Nullmodemkabel spielt jedem anderen Rechner vor er sei ein Modem. Dies gelingt in dem man die Anschlussbelegung der beiden Kabelenden an der seriellen Schnittstelle ändert. Somit lassen sich bequem Daten von dem einen PC zum anderen senden. Dies funktioniert auch von Linux auf Windows. Nehmen Sie für Linux als Terminalprogramm getty und für Windows das HyperTerminal. Entweder Sie basteln sich ein Nullmodemkabel selbst zusammen, oder sie kaufen sich eins für etwa 5-10 Euro in jedem guten Elektro-oder PC-Laden.
Zugegeben, in der Zeit der GUI`s mag dieses Thema (Terminal-E/A) altertümlich erscheinen, aber wenn es um Netzwerk-Programmierung geht sind Terminals unschlagbar. Das Kapitel Terminal E/A handelt z.B. von solchen Themen:
Bevor Sie anfangen, folgen noch schnell die zwei Möglichkeiten die Ihnen für den Terminal-Modi zur Verfügung stehen:
Jetzt will ich Ihnen zeigen, wie es möglich ist einzelne Tasten von einem Programm abzufangen bzw. auszugebende Zeichen zu manipulieren. Alle Attribute die man bei einem Terminal setzen bzw. abfragen kann, sind in einer Struktur, in der Headerdatei <termios.h> definiert. Hier die Struktur ...
struct termios { tcflag_t c_iflag; /*Eingabe-Flag*/ tcflag_t c_oflag; /*Ausgabe-Flag*/ tcflag_t c_cflag; /*Kontroll-Flag*/ tcflag_t c_lflag; /*Lokale Flags*/ cc_t c_cc[NCCS]; /*Steuerzeichen*/ };
Jetzt benötigen Sie noch die Kenntnis, welche Werte Sie mit den einzelnen Strukturvariablen setzen bzw. erfragen können.
Zuerst die Werte des Eingabe-Flag tcflag_t c_iflag (Eingabe-Flags) die möglich sind ...
Konstante | Bedeutung |
BRKINT | Generieren von SIGINT bei Tastendruck auf BREAK |
ICRNL | Umwandeln von CR in NL bei der Eingabe |
IGNBRK | Break Ignorieren |
IGNCR | CR Ignorieren |
IGNPAR | Bytes mit Paritätsprüfung ignorieren |
IMAXBEL | Akustisches Signal wenn Eingabepuffer voll ist BREAK ignorieren |
INLCR | Umwandeln von NL in CR bei CR ignorieren der Eingabe |
INPCK | Einschalten der Eingabe-Partitätsprüfung |
ISTRIP | Abschneiden des 8.Bit bei Eingabezeichen |
IUCLC | Umwandeln von Groß in Kleinbuchstaben |
IXANY | Wartet auf ein X-beliebiges Zeichen um mit der Ausgabe fortzusetzen |
IXOFF | Einschalten des START/STOP - Eingabeprotokolls |
IXON | Einschalten des START/STOP - Ausgabeprotokolls |
PARMRK | Markieren von Partitätsfehler |
Kommen wir
nun zu den Werten des Ausgabe-Flag 'tcflag_t c_oflag' (Ausgabe-Flags)........
Konstante | Bedeutung |
BSDLY | Verzögerungsart für Backspace (BS0 oder BS1) |
CRDLY | Verzögerungsart für CR (CR0,CR1,CR2,CR3) |
FFDLY | Verzögerungsart für form-feed (FF0 oder FF1) |
NLDLY | Verzögerungsart für NL (NL1 oder NL2) |
OCRNL | Umwandeln von CR in NL |
OFDEL | Auffüllzeichen ist DEL sonst NUL |
OFILL | Auffüllzeichen anstatt einer zeitlichen Verzögerung |
OLCUC | Umwandeln von Klein-in Großbuchstaben |
ONLCR | Umwandeln von NL in CR |
ONLRET | Einstellen von NL auf CR |
ONOCR | Unterdrücken von CR in Spalte 0 |
ONOEOT | Ignorieren von STRG+D |
OPOST | Ein implemtierungsdefinierte Ausgabeart einschalten |
OXTABS | Umwandeln von TAB in Leerzeichen |
TABDLY | Verzögerungsart für horizontale Tabs (TAB0 bis TAB3) |
VTDLY | Verzögerungsart für vertikale Tabs (VT0 und VT1) |
Jetzt wollen
wir uns anschauen welche Kontrollflags (tcflag_t c_cflag) wir verwenden können...
Konstante | Bedeutung |
CCTS_OFLOW | Einschalten des CTS-Ausgabeprotokolls |
CIGNORE | Ignorieren von Kontroll-Flags |
CLOCAL | Ausschalten der Modem-Steuerung |
CREAD | Aktivieren des Empfängers |
CRTS_IFLOW | Einschalten des RTS-Eingabeprotokolls |
CRTSCTS | Einschalten der Hardware-Flußkontrolle(RTS und CTS) |
CSIZE | Bitanzahl für ein Zeichen (CS5 bis CS8) |
CSTOPB | Zwei Stop-Bits anstelle von einem senden |
HUPCL | Verbindungsabbruch bei Beendigung des letzten Prozesses |
MDMBUF | Ausgabeprotokoll entsprechend dem
Modem-Carrier-Flag |
PARENB | Einschalten von Paritätsprüfung. |
PARODD | Ungerade Parität, sonst gerade. |
Als letztes
noch ein Überblick zu den Lokalen Flags (tcflag_t c_lflag).......
Konstante | Bedeutung |
ECHO | Einschalten der ECHO - Funktion |
ECHOCTL | Darstellung von Steuerzeichen als Zeichen |
ECHOE | Gelöschte Zeichen mit Leerzeichen überschreiben |
ECHOK | Zeichen löschen oder zur Neueingabe in neue Zeile positionieren |
ECHOKE | Zeichen beim Löschen einer Zeile entfernen |
ECHONL | Ausgabe von NL |
ECHOPRT | Ausgabe von gelöschten Zeichen für Hardcopy |
FLUSHO | Leeren des Ausgabepuffer wie fflush() |
ICANON | Zeilenorientierter Eingabemodus |
IEXTEN | Einschalten des erweiterten Zeichensatzes für die Eingabe |
ISIG | Sonderbedeutung von Terminal-Sonderzeichen einschalten |
NOFLSH | Abschalten des Leerens von Puffern bei INTR oder QUIT |
NOKERNINFO | Ausschalten der Kern-Ausgabe bei STATUS |
PENDIN | Neuausgabe von nichtverarbeitende Eingabezeichen |
TOSTOP | Senden des Signals SIGTTOU bei der Ausgabe durch Hintergrundprozesse |
XCASE | Umwandeln von eingegebenen Groß- in Kleinbuchstaben |
Jetzt wollen Sie aber auch wissen, wie Sie die Terminal-Flags einsetzen können? Kommen wir also zu den ersten beiden Funktionen, die in der Headerdatei <termios.h> definiert sind ...
int tcgetattr(int fd, struct termios *terminal_zeiger); int tcsetattr(int fd, int option, struct termios *terminal_zeiger);
Wie man aus den Namen der Funktionen sicherlich bereits herauslesen kann, dient tcgetattr() dazu die Attribute zu ermitteln und tcsetattr() die Attribute zu setzen. Für den Dateidesktiptor fd geben Sie an, was sie Manipulieren bzw. Abfragen wollen (0 oder SDTIN_FILENO(Standarteingabe) - 1 oder SDTOUT_FILENO (Standartausgabe)). Die Funktionen liefern beide bei Fehler -1 zurück ansonsten 0. Folgende Optionen können Sie mit tcsetattr() angeben ...
Um nun die Attribute eines Terminals abzufragen, gehen Sie wie folgt vor ...
struct termios aktuell; if(tcgetattr(fd, &aktuell) < 0) { /*Fehler*/ ....
Das Ganze nun in einem kurzem Beispiel ...
#include <stdio.h> #include <unistd.h> #include <termios.h> int main(int arg, char **argv) { struct termios aktuell; if(tcgetattr(STDIN_FILENO, &aktuell) < 0) { printf("Kann die Abfrage: Standarteingabe Terminal nicht ausführen"); exit(0); } if(aktuell.c_iflag == BRKINT) printf("Taste BREAK bewirkt SIGINT\n"); if(aktuell.c_iflag != IMAXBEL) printf("Wenn Tasturpuffer voll gibt es kein akkustisches Signal\n"); return 0; }
Mit ...
if(tcgetattr(STDIN_FILENO, &aktuell) < 0)
... erfragen Sie nach dem Attribut der Standardeingabe und mit aktuell vom Typ struct termios können Sie jetzt die einzelnen Attributen abfragen mit ...
if(aktuell.c_iflag == BRKINT)
Hier fragen Sie zum Beispiel ab, ob das Flag BRKINT gesetzt ist (Beschreibung BRKINT siehe oben in der Tabelle).
Bevor ich Ihnen ein weiteres Beispiel zeige, benötigen noch die Kenntnis einer Variablen, in der Struktur termios die noch nicht zur Sprache kam. Das Array c_cc. Es enthält alle Sonderzeichen die durch das Programm verändert werden können ...
Konstante | Bedeutung |
VEOF | Dateiende |
VEOL | Zeilenende |
VERASE | letztes Zeichen löschen |
VINTR | Unterbrechungssignal SIGINT |
VKILL | Zeile löschen |
VQUIT | Abbruch ala SIGQUIT |
VSTOP | Ausgabe anhalten |
VSTART | Ausgabe fortsetzen |
VSTATUS | Statusinformationen anfordern |
VSUSP | Einen Prozess suspendieren |
VWERASE | Letztes Wort löschen |
VMIN | Anzahl der Bytes die gelesen werden müssen bevor read() zurückkehrt |
Weiter Eingabezeichen finden Sie unter /usr/include/termbits.h oder /usr/include/asm/termbits.h