![]() |
|
|
Außer den beiden Flags IXOFF und IXON sollte Ihnen die Bedeutung der einzelnen Flags recht verständlich sein. Zu IXOFF und IXON folgt hierfür noch eine genauere Erläuterung.
Jetzt zu den Werten des Ausgabeflags tcflag_t c_oflag:
Als Nächstes folgt ein Überblick zu den Kontrollflags tcflag_t c_cflag:
Zum Schluss folgt der Überblick zu den lokalen Flags (tcflag_t c_lflag):
Die Funktionen, womit Sie auf die eben aufgelisteten Flags der Struktur termios und ihre Mitglieder zugreifen können, sind: #include <termios.h> #include <unistd. h.> 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 herauslesen kann, dient tcgetattr() dazu, die Attribute eines Terminals zu ermitteln, und tcsetattr() dazu, die Attribute zu setzen. Für den Dateideskriptor fd geben Sie den Filedeskriptor an, den Sie verändern bzw. abfragen wollen – 0 bzw. STDIN_FILENO (Standardeingabe) oder 1 bzw. SDTOUT_FILENO (Standardausgabe). Die Funktionen liefern beide bei einem Fehler –1, ansonsten, wenn alles planmäßig verlief, 0 zurück. Mit dem Argument option bei tcsetattr() können Sie angeben, wann die Veränderungen aktiv werden sollen. Folgende Flags können dabei verwendet werden:
Bevor Sie zur Praxis schreiten, benötigen Sie noch die Kenntnis über eine Variable 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. Hier einige Sonderzeichen dazu. Weitere Zeichen finden Sie unter /usr/include/termbits.h oder /usr/include/asm/termbits.h.
Dazu ein einfaches Beispiel, womit Sie das Zeichen für EOF, das mit (STRG)+(C) generiert wird, verändern können. Im Beispiel wird auch EOF ausgelöst, wenn Sie die (ESC)-Taste drücken. Die Tastenkombination (STRG)+(C) bleibt allerdings trotzdem erhalten. /* my_eof.c */ #include <stdio.h> #include <unistd. h.> #include <termios.h> #include <stdlib.h> #include <string.h> #include <errno.h> int main (void) { struct termios term; int c; if ((tcgetattr (STDIN_FILENO, &term)) < 0) { printf ("Fehler bei tcgetattr (%s) \n", strerror(errno)); exit (EXIT_FAILURE); } // ASCII-Code 27 = ESC == EOF term.c_cc[VEOF] = 27; if ((tcsetattr (STDIN_FILENO, TCSAFLUSH, &term)) < 0) { printf ("Fehler bei tcsetattr (%s) \n", strerror(errno)); exit (EXIT_FAILURE); } printf("Eingabe machen (mit ESC abbrechen)\n"); while ((c = getchar ()) != EOF) putchar (c); return EXIT_SUCCESS; } Das Programm bei der Ausführung: $ gcc -o my_eof my_eof.c $ ./my_eof Eingabe machen (mit ESC abbrechen) Eine Eingabe Eine Eingabe [ESC] In diesem Beispiel haben Sie das Sonderzeichen EOF verändert. Mit der Angabe von term.c_cc[VEOF] = 27; bekommt das Sonderzeichen EOF (VEOF) den ASCII-Code 27 zugewiesen, der dem Escape-Zeichen entspricht. Mit if((tcsetattr(STDIN_FILENO, TCSAFLUSH, &term)) > 0) setzen Sie die Attributsänderung in Kraft. Jetzt folgt der Test, ob es auch funktioniert: while((c=getchar()) != EOF) putchar(c); So lange, bis Sie EOF betätigen, könne Sie etwas mit der Tastatur eingeben. In diesem Beispiel wäre das Programm zu Ende, wenn die Escape-((ESC))-Taste gedrückt wird statt, wie gewöhnlich verwendet, die Tastenkombination (STRG)+(D). Da nicht jeder sämtliche ASCII-Code-Zeichen im Kopf hat – geschweige den Wert der Sonderzeichen –, ist in der Headerdatei <termios.h> noch folgendes Makro definiert: #ifndef CTRL #define CTRL(ch) ((ch)&0x1F) #endif Falls dies bei Ihnen nicht vorhanden sein sollte, so wissen Sie ja jetzt, wie Sie es selbst definieren können. Damit können Sie die Eingabe eines Sonderzeichens, z. B. die Tastenkombination (STRG)+(Y), folgendermaßen festlegen: term.c_cc[VEOF] = CTRL('Y');
Hiermit würden Sie mit der Tastenkombination (STRG)+(Y) das EOF-Zeichen generieren. 13.1.2 Flags setzen und löschen
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Flag(s) setzen: |
| Flag(s) löschen: |
Hierzu folgt ein einfaches Beispiel, in dem Sie eine Linux-übliche Passworteingabe machen können. Im Beispiel wird das Flag ECHO abgeschaltet, womit die Eingabe nicht am Bildschirm angezeigt wird. Das Flag ECHONL hingegen wird eingeschaltet, damit nach Eingabe des Passwortes durch Betätigung von (ENTER) dieses Newline-Zeichen ausgegeben wird – und das Programm auch sauber in der nächsten Zeile fortfährt. Am Ende stellen Sie den zuvor gesicherten Terminalzustand wieder her.
/* my_getpass.c */ #include <termios.h> #include <stdio.h> #include <stdlib.h> #define PASS 8 static char *my_getpass (void) { struct termios origstate, changedstate, teststate; char passwort[PASS]; char *p = passwort; /* alten Terminalzustand speichern (von stdin = id 0) */ if (tcgetattr (0, &origstate) != 0) printf ("tcgetattr failed"); changedstate = origstate; /* neuen Terminalzustand setzen (von stdin = id 0) */ /* Ausgabe ausschalten */ changedstate.c_lflag &= ~ECHO; /* Newline beachten (einschalten) */ changedstate.c_lflag |= ECHONL; if (tcsetattr (0, TCSANOW, &changedstate) != 0) printf ("tcsetattr failed"); /* Überprüfen, ob der Terminalzustand erfolgreich */ /* verändert wurde */ tcgetattr (0, &teststate); if (teststate.c_lflag & ECHO) printf ("ECHO-Flag konnte nicht abgeschaltet werden\n"); if (!teststate.c_lflag & ECHONL) printf ("ECHONL konnte nicht eingeschaltet werden\n"); fprintf(stdout,"Passwort eingeben : "); fgets(passwort, PASS, stdin); /* alten Terminalzustand wiederherstellen */ /* (von stdin = id 0) */ if (tcsetattr (0, TCSANOW, &origstate) != 0) printf ("tcsetattr failed"); return p; } int main (void) { char *ptr = my_getpass(); printf("Ihre Eingabe war: %s\n",ptr); return EXIT_SUCCESS; }
Das Programm bei der Ausführung:
$ gcc -o my_getpass my_getpass.c $./my_getpass Passwort eingeben :******** Ihre Eingabe war: juergen
Jetzt zu einem weiteren Beispiel, das Ihnen zeigt, wie Sie bestimmte Steuerzeichen von der Tastatur abfragen können. Im Beispiel werden Tastendrücke wie (F1), (F2), die Pfeiltasten oben, unten, rechts und links, (Page_˝), (Page_Ľ)und (Home) überprüft. Sie können dies natürlich noch weiter ausstricken. Dabei werden die lokalen Flags ECHO, ICANON und ISIG abgeschaltet. Sie sollten das Beispiel außerdem in einem echten Terminal ausführen, damit es richtig läuft – sonst wird z. B. (F1) nicht angezeigt. Ein echtes Terminal können Sie durch gleichzeitiges Drücken von (STRG)+(ALT)+(F1) öffnen. Zurück zu Ihrer grafischen Oberfläche kommen Sie wieder mit der Tastenkombination (STRG)+(ALT)+(F7). Das Programm ist recht ordentlich dokumentiert, womit ich mir weitere Erklärungen ersparen kann.
/* keystroke.c */ #include <stdio.h> #include <unistd. h.> #include <termios.h> #include <stdlib.h> #include <string.h> /*Altes Terminal wiederherstellen */ static struct termios BACKUP_TTY; /* Eingabekanal wird so umgeändert, damit die Tasten */ /* einzeln abgefragt werden können */ static int new_tty (int fd) { struct termios buffer; /* Wir fragen nach den Attributen des Terminals und */ /* übergeben diese dann an buffer. BACKUP_TTY dient */ /* bei Programmende zur Wiederherstellung der alten */ /* Attribute und bleibt somit unberührt. */ if ((tcgetattr (fd, &BACKUP_TTY)) == -1) return -1; buffer = BACKUP_TTY; /* Lokale Flags werden gelöscht : */ /* ECHO - Zeichenausgabe auf Bildschirm */ /* ICANON - Zeilenorientierter Eingabemodus */ /* ISIG – Terminal-Steuerzeichen (kein STRG+C mehr */ /* möglich) */ buffer.c_lflag = buffer.c_lflag & ~(ECHO | ICANON | ISIG); /* VMIN=Anzahl der Bytes, die gelesen werden müssen, */ /* bevor read() zurückkehrt */ /* In unserem Beispiel 1 Byte für 1 Zeichen */ buffer.c_cc[VMIN] = 1; /*Wir setzen jetzt die von uns gewünschten Attribute*/ if ((tcsetattr (fd, TCSAFLUSH, &buffer)) == -1) return -1; return 0; } /*Ursprüngliches Terminal wiederherstellen*/ static int restore_tty (int fd) { if ((tcsetattr (fd, TCSAFLUSH, &BACKUP_TTY)) == -1) return -1; return 0; } int main (int argc, char **argv) { int rd; char c, buffer[10]; /*Setzen des neuen Modus*/ if (new_tty (STDIN_FILENO) == -1) { printf ("Fehler bei der Funktion new_tty()\n"); exit (EXIT_FAILURE); } do { /*Erste Zeichen lesen*/ if (read (STDIN_FILENO, &c, 1) < 1) { printf ("Fehler bei read\n"); restore_tty (STDIN_FILENO); exit (EXIT_FAILURE); } /*Haben wir ein ESC ('\E') gelesen? */ if (c == 27) { /* Ja, eine Escape-Sequenz, wir wollen den Rest */ /* der Zeichen auslesen */ rd = read (STDIN_FILENO, buffer, 4); buffer[rd] = '\0'; /*String terminieren */ /*Folg. Werte haben die Funktionstasten in der Term */ /* F1 = \E[[A */ /* F2 = \E[[B */ /* PFEIL RECHTS= \E[C */ /* PFEIL LINKS = \E[D */ /* PFEIL RUNTER= \E[B */ /* PFEIL HOCH = \E[A */ /* POS 1 = \E[1~ */ /* BILD RUNTER = \E[6~ */ /* BILD HOCH = \E[5~ */ if (strcmp (buffer, "[[A") == 0) printf ("F1\n"); if (strcmp (buffer, "[[B") == 0) printf ("F2\n"); if (strcmp (buffer, "[C") == 0) printf ("->\n"); if (strcmp (buffer, "[D") == 0) printf ("<-\n"); if (strcmp (buffer, "[B") == 0) printf ("V\n"); if (strcmp (buffer, "[A") == 0) printf ("^\n"); if (strcmp (buffer, "[1~") == 0) printf ("POS 1\n"); if (strcmp (buffer, "[6~") == 0) printf ("BILD RUNTER\n"); if (strcmp (buffer, "[5~") == 0) printf ("BILD HOCH\n"); /* Nein, kein ESC ... */ } else { if ((c < 32) || (c == 127)) /*Nummerischen Wert ausgeben */ printf ("%d\n", c); else /*Zeichen ausgeben */ printf ("%c\n", c); } } while (c != 'q'); restore_tty (STDIN_FILENO); return EXIT_SUCCESS; }
Das Programm bei der Ausführung:
$ gcc -o keystroke keystroke.c $ ./keystroke ^ -> <- V BILD HOCH BILD RUNTER F1 F2 POS1 q
Zum Abschluss noch ein Beispiel, wie Sie eine einzelne Taste abfragen bzw. abfangen können. Dazu müssen Sie das Terminal in den Raw-Modus schalten – oder besser wäre wohl abschalten. Denn wie der Name raw (für roh, unbearbeitet) schon andeutet, handelt es sich hier um einen fast nackten Terminalmodus – dabei werden vorwiegend Flags ausgeschaltet. Lediglich das Kontrollflag, wie groß ein Zeichen in Bits ist, wird dabei gesetzt.
/* my_getch.c */ #include <stdio.h> #include <unistd. h.> #include <termios.h> #include <stdlib.h> static struct termios new_io; static struct termios old_io; /* Funktion schaltet das Terminal in den Raw-Modus: */ /* Folgende Eingabeflags werden gelöscht: */ /* BRKINT, ICRNL, INPCK, ISTRIP, IXON */ /* Folgende Kontrollflags werden gelöscht: CSIZE, PERENB */ /* Folgende Ausgabeflags werden gelöscht: OPOST */ /* Folgende lokale Flags werden gelöscht: */ /* ECHO, ICANON, IEXTEN, ISIG */ /* Gesetzt wird das Kontrollflag CS8, was bedeutet, */ /* dass ein Zeichen 8 Bit breit ist */ /* Steuerzeichen: Leseoperation liefert 1 Byte VMIN=1 VTIME=1 */ static int raw (int fd) { /* Sichern unseres Terminals */ if ((tcgetattr (fd, &old_io)) == -1) return -1; new_io = old_io; /* Wir verändern jetzt die Flags für den Raw-Modus */ new_io.c_iflag = new_io.c_iflag & ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON); new_io.c_oflag = new_io.c_iflag & ~(OPOST); new_io.c_cflag = new_io.c_cflag & ~(CSIZE | PARENB); new_io.c_lflag = new_io.c_lflag & ~(ECHO|ICANON|IEXTEN|ISIG); new_io.c_cflag = new_io.c_cflag | CS8; new_io.c_cc[VMIN] = 1; new_io.c_cc[VTIME] = 0; /*Jetzt setzen wir den Raw-Modus*/ if ((tcsetattr (fd, TCSAFLUSH, &new_io)) == -1) return -1; return 0; } /*Funktion zur Abfrage einer Taste*/ static int getch () { int c; if (raw (STDIN_FILENO) == -1) { printf ("Fehler bei der Funktion raw()\n"); exit (EXIT_FAILURE); } c = getchar (); /*Alten Terminalmodus wiederherstellen*/ tcsetattr (STDIN_FILENO, TCSANOW, &old_io); return c; } int main (void) { int zeichen; printf ("Warte auf'q', um das Programm zu beenden\n"); while ((zeichen = getch ()) != 'q') printf ("'%c' != 'q'\n", zeichen); printf ("'%c' == 'q'\n", zeichen); printf ("ENDE\n"); return EXIT_SUCCESS; }
Das Programm bei der Ausführung:
$ gcc -o my_getch my_getch.c $ ./my_getch Warte auf'q', um das Programm zu beenden 'a' != 'q' 's' != 'q' 'd' != 'q' 'f' != 'q' 'j' != 'q' 'k' != 'q' 'l' != 'q' 'ö' != 'q' 'q' == 'q' ENDE
Die Funktion raw() schaltet das Terminal in den Raw-Modus, und mit der Funktion getch() können Sie dann nach einer einzelnen oder irgendeiner Taste fragen. Den großen Overhead der Funktion raw() können Sie sich ersparen, da Linux/UNIX dafür eine Funktion für uns bereithält:
#include <termios.h> int cfmakeraw(struct termios *tty_zeiger);
Diese Funktion ist ebenfalls in der Headerdatei <termios.h> definiert und erleichtert Ihnen den Schritt, das Terminal in den Raw-Modus zu setzen.
Um den Namen des Terminals zu erfragen, der gerade die Kontrolle hat, können Sie folgende Funktion verwenden:
#include <stdio.h> char *ctermid(char *s);
Die Funktion ctermid() gibt einen String mit dem Pfadnamen des Kontrollterminals für den aktuellen Prozess zurück. In den meisten Fällen dürfte dies /dev/tty sein. Für s sollten Sie mindestens L_ctermid Bytes Speicherplatz reservieren. Die symbolische Konstante L_ctermid ist in der Headerdatei <stdio.h> definiert. Die Funktion gibt bei Erfolg einen Zeiger auf einen Puffer zurück, der auf den Namen des Kontrollterminals verweist, ansonsten wird bei einem Fehler NULL zurückgegeben. Hierzu ein kurzes Beispiel der Funktion ctermid():
/* my_tty.c */ #include <stdio.h> #include <stdlib.h> #include <unistd. h.> #include <termios.h> static char termname[L_ctermid]; int main (void) { const char *ptr = ctermid (termname); if (ptr != NULL) printf ("Kontrollterminalname = %s\n", ptr); else printf("Konnte Terminalname nicht ermitteln\n"); return EXIT_SUCCESS; }
Wenn Sie die Adresse des Terminalpfadnamens benötigen, können Sie die folgende Funktion verwenden:
char *ttyname(int fd);
Die Funktion liefert einen nullterminierten Pfadnamen (in einem statischen Speicherbereich) des Terminalgerätes zurück, womit der Filedeskriptor fd geöffnet wurde. Bei einem Fehler oder wenn fd mit keinem Terminal verbunden ist, wird NULL zurückgegeben. Auch hierzu ein einfaches Beispiel:
/* sende.c */ #include <stdio.h> #include <stdlib.h> #include <unistd. h.> #include <termios.h> int main(int argc, char **argv) { printf("Nachricht von Terminal %s\n%s", ttyname(STDIN_FILENO), *++argv); return EXIT_SUCCESS; }
Öffnen Sie nun zwei Pseudo-Konsolen (pts) unter X. Ermitteln Sie zuerst mit diesem Programm den Pfad der Konsole (tty). In meinem Beispiel hat Konsole 1 den Pfad /dev/pts/2 und Konsole 2 den Pfad /dev/pts/3. Führen Sie das Programm folgendermaßen aus (der Programmname sei sende):
---[/dev/pts/2]--- $ ./sende hallo > /dev/pts/3
Auf der Konsole /dev/pts/3 steht jetzt:
---[/dev/pts/3]--- Nachricht von Terminal /dev/pts/2 hallo
Wenn Sie wollen, können Sie jetzt vom Terminal /dev/pts/3, wie eben gemacht, eine Nachricht an /dev/pts/2 senden. Dies funktioniert daher, da Sie mit
ttyname(STDIN_FILENO)
den Terminalnamen der Standardeingabe abfragen. Sie können ja statt der Standardeingabe die Standardausgabe abfragen (STDOUT_FILENO).
Jetzt zu einigen Funktionen, womit Sie die Geschwindigkeit der Ein-/Ausgabe eines Terminalgerätes verändern oder erfragen können. Diese Schnittstelle ist schon sehr alt, weshalb hier für die Geschwindigkeit noch Baud verwendet wird. Die korrekte Bezeichnung würde Bits pro Sekunde (bps) lauten. Damit können Sie zum Beispiel testen, wie die Geschwindigkeit zwischen zwei Terminals im Netzwerk ist. Folgende Funktionen stehen Ihnen zum Erfragen der Geschwindigkeit zur Verfügung:
#include <termios.h> speed_t cfgetispeed(const struct termios *tty_zeiger); speed_t cfgetospeed(const struct termios *tty_zeiger);
Beide Funktionen sind in der Headerdatei termios.h definiert und geben die momentan gesetzte Baudrate zurück, wobei cfgetispeed() die Geschwindigkeit der Eingabe und cfgetospeed() die Geschwindigkeit der Ausgabe zurückgibt. Folgende Konstanten sind hierfür auf alle Fälle definiert:
B0,B50,B75,B110,B134,B150,B200,B300,B600, B1200,B1800,B2400,B4800,B9600,B19200,B38400
Wobei B0 für die Beendigung einer Verbindung steht. Weiterhin können (unter Linux auf alle Fälle) vorhanden sein:
B57600,B115200,B230400,B460800
Angewendet werden diese Funktionen folgendermaßen:
baudrate = funktion_erfrage_baudrate(cfgetispeed(&terminal));
...
unsigned long funktion_erfrage_baudrate(speed baudkonstante) {
if(baudkonstante == B0) return(0);
else if(baudkonstante == B50) return(50);
else if(baudkonstante == B75) return(75);
...
...
else if(baudkonstante == B460800) return(460800);
else return -1;
}
Hier das Beispiel, womit Sie die Baudrate eines Terminalgerätes erfragen, das Sie in der Kommandozeile als zweites Argument mit angeben.
/* baud.c */ #include <stdio.h> #include <unistd. h.> #include <termios.h> #include <fcntl.h> #include <stdlib.h> #include <errno.h> typedef unsigned long Ulong; typedef struct termios TTY; static speed_t baud_konstante[] = { B0, B50, B75, B110, B134, B150, B200, B300, B600, B1200, B1800, B2400, B4800, B9600, B19200, B38400, B57600, B115200, B230400/*, B460800 */ }; static Ulong baud_werte[] = { 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, 9600, 19200, 38400, 57600, 115200, 230400/*, 460800 */ }; static Ulong baudrate_wert (speed_t baud) { int i; for (i = 0; i <= 19; i++) { if (baud == baud_konstante[i]) return (baud_werte[i]); } return -1; } int main (int argc, char **argv) { int fd; speed_t baud_input, baud_output; TTY terminal; if (argc != 2) { printf ("Usage: %s Gerätepfad\n", *argv); exit (EXIT_FAILURE); } if ((fd = open (argv[1], O_RDWR | O_NONBLOCK)) == -1) { perror ("fopen()"); exit (EXIT_FAILURE); } if (isatty (fd) == 0) { printf ("%s ist keine tty\n", argv[1]); exit (EXIT_FAILURE); } if (tcgetattr (fd, &terminal) == -1) { printf ("Fehler bei tcgetattr()\n"); exit (EXIT_FAILURE); } if((baud_input=baudrate_wert(cfgetispeed(&terminal))) == -1) { printf ("Fehler bei baud_input ...\n"); exit (EXIT_FAILURE); } if((baud_output=baudrate_wert(cfgetospeed(&terminal))) == -1) { printf ("Fehler bei baud_output ...\n"); exit (EXIT_FAILURE); } printf ("Eingabe-Baudrate : %d\n", baud_input); printf ("Ausgabe-Baudrate : %d\n", baud_output); return EXIT_SUCCESS; }
Das Programm bei der Ausführung:
$ gcc -o baud baud.c $ ./baud /dev/tty Eingabe-Baudrate : 38400 Ausgabe-Baudrate : 38400
Neu in diesem Programm ist die Funktion:
#include <unistd. h.> int isatty(int fd);
Damit können Sie abfragen, ob ein Filedeskriptor auf das Terminal eingestellt ist. Wichtig an den Funktionen cfget...() und cfset...() ist, wenn Sie mit cfgetispeed() etwas abfragen wollen, führen Sie zuerst mit der Funktion tcgetattr() die Struktur termios für das betreffende Gerät eine Abfrage aus. Dasselbe gilt auch, wenn Sie die beiden folgenden Funktionen einsetzen wollen.
#include <termios.h> int cfsetispeed( struct termios *termzeiger, speed_t baudrate ); int cfsetospeed( struct termios *termzeiger, speed_t baudrate);
Auch hier müssen Sie die Aufrufe erst mit dem tcsetattr()-Aufruf aktivieren. Hier das Beispiel, erweitert um die Möglichkeit, die Baudrate auf 115200 hoch zu setzen.
/* setbaud.c */ #include <stdio.h> #include <unistd. h.> #include <termios.h> #include <fcntl.h> #include <stdlib.h> #include <stdarg.h> typedef unsigned long Ulong; typedef struct termios TTY; static speed_t baud_konstante[] = { B0, B50, B75, B110, B134, B150, B200, B300, B600, B1200, B1800, B2400, B4800, B9600, B19200, B38400, B57600, B115200, B230400/*, B460800 */ }; static Ulong baud_werte[] = { 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, 9600, 19200, 38400, 57600, 115200, 230400/*, 460800 */ }; // R. W. Stevens-like Fehlerbehandlung static void fehler_exit (char *error_msg, ...) { va_list az; va_start (az, error_msg); vprintf (error_msg, az); va_end (az); exit (EXIT_FAILURE); } static Ulong baudrate_wert (speed_t baud) { int i; for (i = 0; i <= 19; i++) { if (baud == baud_konstante[i]) return (baud_werte[i]); } return -1; } int main (int argc, char **argv) { int fd; speed_t baud_input, baud_output; TTY terminal; if (argc != 2) fehler_exit ("Bitte einen Gerätepfad mit angeben\n"); if ((fd = open (argv[1], O_RDWR | O_NONBLOCK)) == -1) fehler_exit ("Konnte %s nicht öffnen\n", argv[1]); if (isatty (fd) == 0) fehler_exit ("%s ist kein tty\n", argv[1]); if (tcgetattr (fd, &terminal) == -1) fehler_exit ("Fehler bei tcgetattr()\n"); if((baud_input=baudrate_wert(cfgetispeed(&terminal))) == -1) fehler_exit ("Fehler bei baud_input ...\n"); if((baud_output=baudrate_wert(cfgetospeed(&terminal))) == -1) fehler_exit ("Fehler bei baud_output ...\n"); printf ("Eingabe-Baudrate : %d\n", baud_input); printf ("Ausgabe_Baudrate : %d\n", baud_output); if ((cfsetispeed (&terminal, B115200)) == -1) fehler_exit("Fehler beim Setzen von Eingabe-Baudrate ...\n"); if ((cfsetospeed (&terminal, B115200)) == -1) fehler_exit("Fehler beim Setzen von Ausgabe-Baudrate ...\n"); if (tcsetattr (fd, TCSAFLUSH, &terminal) == -1) fehler_exit ("Fehler bei tcsetattr ...\n"); if (tcgetattr (fd, &terminal) == -1) fehler_exit ("Fehler bei tcgetattr ...\n"); if((baud_input=baudrate_wert(cfgetispeed(&terminal))) == -1) fehler_exit ("Fehler bei baud_input ...\n"); if((baud_output=baudrate_wert(cfgetospeed(&terminal))) == -1) fehler_exit ("Fehler bei baud_output ...\n"); printf ("Eingabe-Baudrate-neu : %d\n", baud_input); printf ("Ausgabe_Baudrate-neu : %d\n", baud_output); return EXIT_SUCCESS; }
Das Programm bei der Ausführung:
$ gcc -o setbaud setbaud.c $ ./setbaud /dev/tty Eingabe-Baudrate : 38400 Ausgabe_Baudrate : 38400 Eingabe-Baudrate-neu : 115200 Ausgabe_Baudrate-neu : 115200
Zum Thema Terminal E/A ließe sich noch eine ganze Menge mehr verfassen. Für den Fall, dass Sie mehr Informationen dazu benötigen, sei die Manual Page (man termios) empfohlen.
| << zurück |
|
||||||||||||
|
||||||||||||
|
||||||||||||
Copyright © Rheinwerk Verlag GmbH 2006
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich
ausdrucken. Ansonsten unterliegt das Openbook denselben Bestimmungen,
wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist
urheberrechtlich geschützt.
Alle Rechte vorbehalten einschließlich der
Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und
Verarbeitung in elektronischen Systemen.