POSIX Terminal Schnittstelle - POSIX terminal interface

Die POSIX-Terminalschnittstelle ist die verallgemeinerte Abstraktion, die sowohl eine Anwendungsprogrammierschnittstelle für Programme als auch eine Reihe von Verhaltenserwartungen für Benutzer eines Terminals umfasst , wie sie im POSIX- Standard und in der Single Unix-Spezifikation definiert sind . Es ist eine historische Entwicklung der Terminalschnittstellen von BSD Version 4 und Seventh Edition Unix .

Allgemeine zugrunde liegende Konzepte

Hardware

Eine Vielzahl von E / A-Geräten wird in Unix-Systemen als "Terminals" angesehen. Diese schließen ein:

Terminal Intelligenz und Fähigkeiten

Intelligenz: Terminals sind dumm, nicht intelligent

Im Gegensatz zu seinen Zeitgenossen für Großrechner und Minicomputer wurde das ursprüngliche Unix-System ausschließlich für dumme Terminals entwickelt, und das ist bis heute der Fall. Ein Terminal ist ein zeichenorientiertes Gerät, das Zeichenströme umfasst, die von dem Gerät empfangen und an das Gerät gesendet werden. Obwohl die Zeichenströme strukturiert sind und Steuerzeichen , Escape-Codes und Sonderzeichen enthalten, ist das E / A-Protokoll nicht so strukturiert wie das E / A-Protokoll von intelligenten oder intelligenten Terminals. Es gibt keine Feldformatspezifikationen. Es gibt keine Blockübertragung ganzer Bildschirme (Eingabeformen) von Eingabedaten.

Im Gegensatz dazu verwenden Mainframes und Minicomputer in geschlossenen Architekturen üblicherweise blockorientierte Terminals .

Fähigkeiten: terminfo, termcap, curses, et al.

Die "Fähigkeiten" eines Terminals umfassen verschiedene dumme Terminalfunktionen, die über das hinausgehen, was von einer reinen Fernschreibmaschine verfügbar ist, die Programme nutzen können. Sie umfassen (hauptsächlich) Escape-Codes, die an das Terminal gesendet oder von diesem empfangen werden können. Die an das Terminal gesendeten Escape-Codes führen verschiedene Funktionen aus, die ein CRT-Terminal (oder ein Software-Terminal-Emulator) nicht für eine Teletypewriter ausführen kann, z. B. das Bewegen des Cursors des Terminals an Positionen auf dem Bildschirm, das Löschen und Scrollen des gesamten Bildschirms oder von Teilen davon , Ein- und Ausschalten angeschlossener Druckergeräte, programmierbarer Funktionstasten, Ändern der Anzeigefarben und -attribute (z. B. umgekehrtes Video ) und Festlegen von Anzeigetitelzeichenfolgen. Der Escape - Codes von dem Terminal signify Dingen wie empfangene Funktionstaste , Pfeil und andere spezielle Tastenanschläge ( Home - Taste , Ende - Taste , Hilfe - Taste , PgUp Schlüssel , PgDn Schlüssel , Einfügen - Taste , Löschtaste , und so weiter).

Diese Funktionen werden in Datenbanken codiert, die von einem Systemadministrator konfiguriert werden und von Programmen aus über die terminfo- Bibliothek (die die ältere termcap- Bibliothek ersetzt) aufgerufen werden , auf der wiederum Bibliotheken wie die curses- und ncurses- Bibliotheken aufgebaut sind. Anwendungsprogramme verwenden die Terminalfunktionen, um Textbenutzeroberflächen mit Fenstern, Dialogfeldern, Schaltflächen, Beschriftungen, Eingabefeldern, Menüs usw. bereitzustellen.

Kontrolle von Umgebungsvariablen: TERM et al.

Die speziellen Funktionen für das Terminal, die die Eingabe und Ausgabe eines (terminalbewussten) Programms verwendet, werden aus der Datenbank abgerufen und nicht fest in Programme und Bibliotheken eingebunden. Sie werden von der TERM Umgebungsvariablen (und optional für die Bibliotheken termcap und terminfo) gesteuert , die TERMCAP und TERMINFO Umgebungsvariablen). Diese Variable wird von jedem Terminalüberwachungsprogramm festgelegt, das die Programme erzeugt, die dieses Terminal dann für seine Ein- und Ausgabe verwenden, oder manchmal explizit. Beispielsweise:

  • Das Programm getty (oder ein gleichwertiges Programm) legt die TERM Umgebungsvariable gemäß einer Systemdatenbank (verschiedene inittab oder die Konfigurationsdateien für die Programme ttymon oder launchd ) fest, die definiert, welche lokalen Terminals an welche seriellen Ports angeschlossen sind und welche Terminaltypen von lokalen virtuellen Terminals bereitgestellt werden oder die lokale Systemkonsole.
  • Ein DFÜ-Benutzer auf einem Remote-Terminal verwendet nicht den Terminaltyp, den das System normalerweise für diese DFÜ-Leitung erwartet, und setzt daher die TERM Umgebungsvariable unmittelbar nach der Anmeldung manuell auf den richtigen Typ. (In der Regel stimmt der vom getty-Programm für die DFÜ-Leitung festgelegte Terminaltyp, den der Systemadministrator am häufigsten von DFÜ-Benutzern mit Remote-Terminals verwendet hat, mit dem vom DFÜ-Benutzer und überein Dieser Benutzer muss den Terminaltyp nicht überschreiben.)
  • Der SSH- Server-Daemon (oder ein gleichwertiger wie der rlogin- Daemon) setzt die TERM Umgebungsvariable auf denselben Terminaltyp wie der SSH-Client.
  • Der Software-Terminal-Emulator legt unter Verwendung eines Pseudoterminals die TERM Umgebungsvariable fest, um den Typ des zu emulierenden Terminals anzugeben. Emulierte Terminals stimmen häufig nicht genau mit der tatsächlichen Terminalhardware überein, und Terminalemulatoren haben Typnamen, die für ihre Verwendung vorgesehen sind. Das Programm xterm wird beispielsweise (standardmäßig) xterm als Terminaltyp festgelegt. Das Programm GNU Screen wird screen als Terminaltyp festgelegt.

Jobkontrolle

Terminals bieten Jobkontrollmöglichkeiten. Interaktiv kann der Benutzer am Terminal Steuerzeichen senden, die den aktuell ausgeführten Job anhalten, zur interaktiven Jobsteuerungs-Shell zurückkehren, die den Job erzeugt hat, und Befehle ausführen, die Jobs im "Hintergrund" platzieren oder einen anderen Hintergrundjob wechseln in den Vordergrund treten (ggf. nicht aufhängen).

Liniendisziplinen

Genau genommen umfasst ein Endgerät in Unices den zugrunde liegenden tty-Gerätetreiber , der für die physische Steuerung der Gerätehardware über E / A-Anweisungen und die Verarbeitung von Geräteunterbrechungsanforderungen für die Zeicheneingabe und -ausgabe sowie die Leitungsdisziplin verantwortlich ist . Eine Leitungsdisziplin ist unabhängig von der tatsächlichen Gerätehardware, und für ein Terminal-Konzentrator- Gerät, das für mehrere Steuerterminals verantwortlich ist, kann dieselbe Leitungsdisziplin verwendet werden wie für ein Pseudoterminal. In der Tat, die Leitungsdisziplin (oder, im Fall von BSD, AIX und anderen Systemen, Linien Disziplinen ) sind die gleiche für alle Endgeräte. Es ist die Zeilendisziplin, die für das lokale Echo, die Zeilenbearbeitung, die Verarbeitung der Eingabemodi, die Verarbeitung der Ausgabemodi und die Zeichenzuordnung verantwortlich ist. All diese Dinge sind unabhängig von der tatsächlichen Hardware und verhalten sich wie in den einfachen Abstraktionen, die von tty-Gerätetreibern bereitgestellt werden: Senden eines Zeichens, Empfangen eines Zeichens, Festlegen verschiedener Hardwarezustände.

In der siebten Ausgabe von Unix , BSD- Systemen und Derivaten, einschließlich macOS und Linux , kann jedes Endgerät zwischen mehreren Leitungsdisziplinen umgeschaltet werden. Im AT & T STREAMS- System sind Leitungsdisziplinen STREAMS-Module, die auf einen STREAMS-E / A-Stapel geschoben und von diesem entfernt werden können.

Geschichte

Die POSIX-Terminalschnittstelle wird von den Terminalschnittstellen verschiedener Unix-Systeme abgeleitet.

Frühe Unices: Seventh Edition Unix

Die von Unix 32V und Seventh Edition Unix bereitgestellte Terminalschnittstelle, die auch von BSD Version 4 als alter Terminaltreiber vorgestellt wurde , war einfach und weitgehend auf Teletypewriter als Terminals ausgerichtet. Die Eingabe wurde zeilenweise eingegeben, wobei der Terminaltreiber im Betriebssystem (und nicht die Terminals selbst) einfache Funktionen zur Zeilenbearbeitung bereitstellte. Ein Puffer wurde von dem Kernel verwaltet, in dem die Bearbeitung stattfand. Anwendungen, die die Terminaleingabe lesen, erhalten den Inhalt des Puffers nur, wenn die return Taste am Terminal gedrückt wurde, um die Zeilenbearbeitung zu beenden. Der @ vom Terminal an das System gesendete Schlüssel löscht ("tötet") den gesamten aktuellen Inhalt des Bearbeitungspuffers und wird normalerweise als ' @ ' - Symbol gefolgt von einer Zeilenumbruchsequenz angezeigt, um die Druckposition auf ein neues Leerzeichen zu verschieben Linie. Der # vom Terminal an das System gesendete Schlüssel löscht das letzte Zeichen am Ende des Bearbeitungspuffers und wird normalerweise als " # " -Symbol angezeigt , das Benutzer als "Rubout" des vorhergehenden Zeichens erkennen müssten (Teletypewriter sind physisch nicht in der Lage, Zeichen zu löschen, sobald sie auf das Papier gedruckt wurden).

Aus programmtechnischer Sicht hatte ein Endgerät Baudraten senden und empfangen , Zeichen "löschen" und "töten" (die, wie erläutert, eine Zeilenbearbeitung durchführten), Zeichen "unterbrechen" und "beenden" ( Signale für alle erzeugen) Prozesse, für die das Terminal ein steuerndes Terminal war), "Start" - und "Stopp" -Zeichen (für die Modemflusssteuerung verwendet ), ein "Dateiende" -Zeichen (das wie ein Wagenrücklauf wirkt, außer dass es vom read() Systemaufruf aus dem Puffer verworfen wird und Dies kann dazu führen, dass möglicherweise ein Ergebnis mit der Länge Null zurückgegeben wird.) und verschiedene Basismodus-Flags, die bestimmen, ob das lokale Echo vom Terminaltreiber des Kernels emuliert wurde, ob die Modemflusssteuerung aktiviert wurde, die Länge verschiedener Ausgangsverzögerungen, die Zuordnung für das Wagenrücklaufzeichen und die drei Eingabemodi.

Die drei Eingabemodi waren:

Linienmodus (auch als "gekochter" Modus bezeichnet)

Im Leitungsmodus führt die Zeilendisziplin alle Zeilenbearbeitungsfunktionen aus und erkennt die Steuerzeichen "Interrupt" und "Quit" und wandelt sie in Signale um, die an Prozesse gesendet werden. Vom Terminal gelesene Anwendungsprogramme empfangen ganze Zeilen, nachdem der Benutzer die Zeilenbearbeitung abgeschlossen hat und die Eingabetaste drückt.

cbreak-Modus

Der cbreak-Modus ist einer von zwei Zeichen-zu-einem-Zeit-Modi. ( Stephen R. Bourne bezeichnete es scherzhaft ( Bourne 1983 , S. 288) als "halbgekochten" und daher "seltenen" Modus.) Die Liniendisziplin führt keine Linienbearbeitung durch, und die Steuersequenzen für Linienbearbeitungsfunktionen werden behandelt als normale Zeicheneingabe. Anwendungsprogramme, die vom Terminal lesen, empfangen Zeichen sofort, sobald sie in der zu lesenden Eingabewarteschlange verfügbar sind . Die Steuerzeichen "Interrupt" und "Quit" sowie die Steuerzeichen für den Modemfluss werden jedoch weiterhin speziell behandelt und aus dem Eingabestream entfernt.

Rohmodus
Der Rohmodus ist der andere der beiden Zeichen-zu-Zeit-Modi. Die Zeilendisziplin führt keine Zeilenbearbeitung durch, und die Steuersequenzen für beide Zeilenbearbeitungsfunktionen und die verschiedenen Sonderzeichen ("Interrupt", "Beenden" und Flusssteuerung) werden als normale Zeicheneingabe behandelt. Vom Terminal gelesene Anwendungsprogramme empfangen sofort Zeichen und empfangen den gesamten Zeichenstrom unverändert, so wie er vom Endgerät selbst stammt.

Die programmatische Schnittstelle zum Abfragen und Ändern all dieser Modi und Steuerzeichen war der ioctl() Systemaufruf . (Dies ersetzt die stty() und gtty() Systemaufrufe von Sixth Edition Unix.) Obwohl dem „Lösch“ und „kill“ Zeichen waren modifizierbar von ihrem Ausfall von # und @ seit vielen Jahren sie die voreingestellten Standardwerte in den Terminalgerätetreiber waren, und auf vielen Bei Unix-Systemen, bei denen die Einstellungen des Endgeräts nur im Rahmen des Anmeldevorgangs geändert wurden, mussten in Systemanmeldeskripten, die nach Eingabe des Benutzernamens und des Kennworts durch den Benutzer ausgeführt wurden, Fehler bei den Anmelde- und Kennwortaufforderungen mithilfe der vererbten historischen Bearbeitungsschlüsselzeichen korrigiert werden von Teletypewriter-Terminals.

BSD: das Aufkommen der Jobkontrolle

Mit den BSD-Unices kamen die Jobsteuerung und ein neuer Terminaltreiber mit erweiterten Funktionen. Diese Erweiterungen enthielten zusätzliche (wieder programmgesteuert modifizierbare) Sonderzeichen:

  • Die Zeichen "Suspend" und "Delayed Suspend" (standardmäßig Control + Z und Control + Y - ASCII SUB und EM ) verursachten die Erzeugung eines neuen SIGTSTP Signals für Prozesse in der steuernden Prozessgruppe des Terminals.
  • Das „Wort löschen“, „wörtliche nächste“ und „Nachdruck“ Zeichen (Standard Control + W , Control + V und Control + R - ASCII ETB , SYN und DC2 ) durchgeführt zusätzliche Leitung Editierfunktionen. "Wort löschen" löschte das letzte Wort am Ende des Zeilenbearbeitungspuffers. Mit "literal next" konnte jedes Sonderzeichen in den Zeilenbearbeitungspuffer eingegeben werden (eine Funktion, die in Seventh Edition Unix etwas unpraktisch über das Backslash-Zeichen verfügbar ist). "Nachdruck" veranlasste die Zeilendisziplin, den aktuellen Inhalt des Zeilenbearbeitungspuffers in einer neuen Zeile erneut zu drucken (nützlich, wenn ein anderer Hintergrundprozess eine Ausgabe generiert hatte, die sich mit der Zeilenbearbeitung vermischt hatte).

Die programmatische Schnittstelle zum Abfragen und Ändern all dieser zusätzlichen Modi und Steuerzeichen war immer noch der ioctl() Systemaufruf, den seine Schöpfer ( Leffler et al. 1989 , S. 262) als "ziemlich überfüllte Schnittstelle" bezeichneten. Die gesamte ursprüngliche Unix-Funktionalität der siebten Ausgabe wurde beibehalten, und die neue Funktionalität wurde über zusätzliche ioctl() Betriebscodes hinzugefügt. Dies führte zu einer deutlich erweiterten Programmoberfläche, die einige doppelte Funktionen aufwies.

System III und System V.

System III führte eine neue Programmierschnittstelle ein, die die separaten ioctl() Operationen der Seventh Edition kombinierte , um Flags abzurufen und zu setzen sowie Steuerzeichen in Aufrufen abzurufen und zu setzen, die eine termio Struktur verwendeten, um sowohl Flags als auch Steuerzeichen zu halten, und die sie in einer einzigen Operation abrufen und setzen konnten in einer anderen einzelnen Operation. Außerdem wurden einige der Flags aus der Seventh Edition-Benutzeroberfläche in mehrere separate Flags aufgeteilt und einige zusätzliche Funktionen hinzugefügt, obwohl die Jobsteuerung oder die Verbesserungen im Kochmodus von 4BSD nicht unterstützt wurden. Beispielsweise wurden die Modi "gekocht", "cbreak" und "roh" der siebten Ausgabe durch unterschiedliche Abstraktionen ersetzt. Die Erkennung von signalerzeugenden Zeichen ist unabhängig vom Eingabemodus, und es gibt nur zwei Eingabemodi: kanonisch und nicht kanonisch. (Dies ermöglicht einen Terminal-Eingangsmodus, der in Seventh Edition und BSD nicht vorhanden ist: Kanonischer Modus mit deaktivierter Signalerzeugung.)

Die Nachfolger von System III, einschließlich System V , verwendeten dieselbe Schnittstelle.

POSIX: Konsolidierung und Abstraktion

Eines der Hauptprobleme, mit denen sich der POSIX-Standard bei der Definition einer allgemeinen Terminalschnittstelle befasste, war die Vielzahl programmatischer Schnittstellen. Obwohl zum Zeitpunkt des Standards das Verhalten von Terminals von System zu System ziemlich einheitlich war, da die meisten Unices die Begriffe Liniendisziplinen und die BSD-Jobsteuerungsfunktionen übernommen hatten, war die programmatische Schnittstelle zu Terminals über den ioctl() Systemaufruf ein Chaos. Verschiedene Einheiten lieferten unterschiedliche ioctl() Operationen mit unterschiedlichen (symbolischen) Namen und unterschiedlichen Flags. Der tragbare Quellcode musste eine erhebliche Menge an bedingter Kompilierung enthalten, um den Unterschieden zwischen den Softwareplattformen Rechnung zu tragen, obwohl sie alle fiktiv Unix waren.

Der POSIX-Standard ersetzt das ioctl() System vollständig durch eine Reihe von Bibliotheksfunktionen (die natürlich über plattformspezifische Operationen unter dem Deckmantel implementiert ioctl() werden können) mit standardisierten Namen und Parametern. Die termio Datenstruktur von System V Unix wurde als Vorlage für die POSIX- termios Datenstruktur verwendet, deren Felder weitgehend unverändert blieben, mit der Ausnahme, dass sie jetzt Alias-Datentypen zur Angabe der Felder verwendeten, sodass sie von Implementierern problemlos über mehrere Prozessorarchitekturen portiert werden konnten als die explizit verlangt unsigned short und char Datentypen des C und C ++ Programmiersprachen (die unbequemen Größen auf einigen Prozessorarchitekturen sein könnte).

POSIX führte auch die Unterstützung für die Jobsteuerung ein, wobei die termios Struktur zusätzlich zu den von System III und System V unterstützten Steuerzeichen Suspend- und Delayed-Suspend-Zeichen enthielt. Es wurden jedoch keine der Erweiterungen für den gekochten Modus von BSD hinzugefügt, obwohl SunOS 4. x, System V Release 4 , Solaris , HP-UX , AIX , neuere BSDs, macOS und Linux haben sie als Erweiterungen für implementiert termios .

Was der Standard definiert

Terminals und Prozessgruppen steuern

Jeder Prozess im System hat entweder ein einzelnes Steuerterminal oder überhaupt kein Steuerterminal. Ein Prozess erbt sein steuerndes Terminal von seinem übergeordneten Terminal, und die einzigen Operationen an einem Prozess bestehen darin, ein steuerndes Terminal durch einen Prozess ohne kontrollierendes Terminal zu erwerben und es durch einen Prozess mit einem steuernden Terminal freizugeben.

Es ist keine tragbare Methode zum Erfassen eines steuernden Terminals definiert, wobei die implementierte Methode definiert ist. Der Standard definiert das O_NOCTTY Flag für den open() Systemaufruf . Auf diese Weise wird verhindert, dass die sonst übliche Methode zum Erfassen eines steuernden Terminals (ein Prozess ohne steuerndes Terminal) eine open() Endgerätedatei ist, die nicht bereits das steuernde Terminal für einen anderen Prozess ist , ohne das O_NOCTTY Flag anzugeben ), lässt aber seine konventionelle Semantik optional.

Jeder Prozess ist auch Mitglied einer Prozessgruppe. Jedes Endgerät zeichnet eine Prozessgruppe auf, die als Vordergrundprozessgruppe bezeichnet wird . Die Prozessgruppen steuern den Terminalzugriff und die Signalübertragung. Am Terminal generierte Signale werden an alle Prozesse gesendet, die Mitglieder der Vordergrundprozessgruppe des Terminals sind. read() und write() I / O - Operationen an einem Endgerät durch einen Prozess, der kein Mitglied des Endgeräts des Vordergrundprozess Gruppe werden und gegebenenfalls können (jeweils) Ursache Signale ( SIGTTIN und SIGTTOU jeweils) bis zu dem rufenden Prozess gesendet werden. Verschiedene Bibliotheksfunktionen, die den Terminalmodus ändern, haben das gleiche Verhalten wie write() , außer dass sie immer die Signale erzeugen, selbst wenn diese Funktionalität für sich write() selbst ausgeschaltet ist.

Die termios Datenstruktur

Die Datenstruktur, die von allen Terminalbibliotheksaufrufen verwendet wird, ist die termios Struktur, deren Definition der Programmiersprache C und C ++ wie folgt lautet:

struct termios {
    tcflag_t c_iflag ;  // Input modes
    tcflag_t c_oflag ;  // Output modes
    tcflag_t c_cflag ;  // Control modes
    tcflag_t c_lflag ;  // Local modes
    cc_t c_cc[NCCS] ;   // Control characters
} ;

Die Reihenfolge der Felder innerhalb der termios Struktur ist nicht definiert, und Implementierungen dürfen nicht standardmäßige Felder hinzufügen. In der Tat müssen Implementierungen nicht standardmäßige Felder zum Aufzeichnen von Eingangs- und Ausgangsbaudraten hinzufügen. Diese werden in der Struktur in einer implementierungsdefinierten Form aufgezeichnet und über Zugriffsfunktionen abgerufen, anstatt wie bei den standardisierten Strukturfeldern durch direkte Manipulation der Feldwerte.

Die Datentyp-Aliase tcflag_t und cc_t sowie die symbolische Konstante NCCS und die symbolischen Konstanten für die verschiedenen Modusflags, Steuerzeichennamen und Baudraten werden alle in einem Standardheader definiert termios.h . (Dies ist nicht zu verwechseln mit dem ähnlich benannten Header termio.h von System III und System V, der eine ähnliche termio Struktur und viele ähnlich benannte symbolische Konstanten definiert. Diese Schnittstelle ist spezifisch für System III und System V und den Code, der sie verwendet nicht unbedingt auf andere Systeme portierbar sein.)

Die Felder der Struktur sind (zusammenfassend, Einzelheiten siehe Hauptartikel):

c_iflag
Flaggen - Eingabemodus zur Steuerung des Ein- Parität, Eingang Newline Übersetzung, Modem Flusskontrolle , 8-Bit - Sauberkeit und Reaktion auf eine (serielle Schnittstelle der) „break“ Zustand
c_oflag
Ausgabemodus-Flags zum Steuern der implementierungsdefinierten Ausgabe-Nachbearbeitung, der Ausgabe-Newline-Übersetzung und der Ausgabeverzögerungen nach dem Senden verschiedener Steuerzeichen
c_cflag
Terminal-Hardware-Steuerflags zur Steuerung des eigentlichen Endgeräts anstelle der Leitungsdisziplin: Anzahl der Bits in einem Zeichen, Paritätstyp, Auflegen-Steuerung und serielle Leitungsflusssteuerung
c_lflag
Lokale Steuerflags zur Steuerung der Leitungsdisziplin anstelle der Terminalhardware: Kanonischer Modus, Echomodus, Erkennung und Verarbeitung von SIGTTOU Signalerzeugungszeichen und Ermöglichen der Erzeugung des Signals durch den write() Systemaufruf

Die Bibliotheksfunktionen sind (zusammenfassend, Einzelheiten siehe Hauptartikel):

tcgetattr()
Fragen Sie die aktuellen Attributeinstellungen eines Endgeräts in einer termios Struktur ab
tcsetattr()
Legen Sie die aktuellen Attributeinstellungen eines Endgeräts in einer termios Struktur fest und warten Sie optional darauf, dass die Ausgabe in der Warteschlange entleert und die Eingabe in der Warteschlange gelöscht wird
cfgetispeed()
Fragen Sie die Eingabe-Baudrate aus den implementierungsdefinierten Feldern in einer termios Struktur ab
cfgetospeed()
Fragen Sie die Ausgabe-Baudrate aus den implementierungsdefinierten Feldern in einer termios Struktur ab
cfsetispeed()
Legen Sie die Eingangsbaudrate in den implementierungsdefinierten Feldern einer termios Struktur fest
cfsetospeed()
Legen Sie die Ausgangsbaudrate in den implementierungsdefinierten Feldern einer termios Struktur fest
tcsendbreak()
Senden Sie ein Modem-Unterbrechungssignal an ein serielles Geräteterminal
tcdrain()
Warten Sie, bis die Ausgabe in der Warteschlange leer ist
tcflush()
Eingaben in der Warteschlange verwerfen
tcflow()
Flusskontrolle ändern
tcgetpgrp()
Fragen Sie die Vordergrundprozessgruppe des Terminals ab
tcsetpgrp()
Stellen Sie die Vordergrundprozessgruppe des Terminals ein

Spezielle Charaktere

Programmatisch veränderbare Sonderzeichen
Feld Bedeutung Abgerufen von read() Anmerkungen
c_cc[VEOF] Ende der Datei Nein Wird nur im kanonischen Modus bearbeitet
c_cc[VEOL] Ende der Linie Ja Wird nur im kanonischen Modus bearbeitet
c_cc[VERASE] "löschen" Nein Wird nur im kanonischen Modus bearbeitet
c_cc[VKILL] "töten" Nein Wird nur im kanonischen Modus bearbeitet
c_cc[VINTR] "unterbrechen" Nein Signalerzeugungszeichen unabhängig vom Eingabemodus
c_cc[VQUIT] "Verlassen" Nein Signalerzeugungszeichen unabhängig vom Eingabemodus
c_cc[VSUSP] "aussetzen" Nein Signalerzeugungszeichen unabhängig vom Eingabemodus
c_cc[VSTOP] "Stopp" Nein Modemflusssteuerzeichen unabhängig vom Eingabemodus
c_cc[VSTART] "Start" Nein Modemflusssteuerzeichen unabhängig vom Eingabemodus

Das c_cc[] Array-Mitglied der termios Datenstruktur gibt alle (programmgesteuert veränderbaren) Sonderzeichen an. Die Indizes in das Array sind symbolische Konstanten, eine für jeden Sonderzeichentyp, wie in der Tabelle rechts. (Zwei weitere Einträge im Array sind für die Eingabeverarbeitung im nicht-kanonischen Modus relevant und werden nachfolgend erläutert.)

Nicht programmgesteuert veränderbare Sonderzeichen sind Zeilenvorschub (ASCII LF ) und Wagenrücklauf (ASCII CR ).

Eingabeverarbeitung

Die Eingabeverarbeitung bestimmt das Verhalten des read() Systemaufrufs auf einem Endgerät sowie die Leitungsbearbeitungs- und Signalerzeugungsmerkmale der Leitungsdisziplin. Im Gegensatz zu Seventh Edition Unix und BSD Version 4 und wie bei System III und System V erfolgt die Zeilenbearbeitung in einem von nur zwei Modi: im kanonischen Modus und im nicht-kanonischen Modus. Der grundlegende Unterschied zwischen ihnen besteht darin, dass unter dem Gesichtspunkt der blockierenden / nicht blockierenden Anforderungen des read() Systemaufrufs (angegeben mit dem O_NONBLOCK Flag im Dateideskriptor über open() oder fcntl() ) Daten "zum Lesen verfügbar" sind.

Verarbeitung im kanonischen Modus

Im kanonischen Modus werden Daten in einem Zeilenbearbeitungspuffer gesammelt und stehen erst dann "zum Lesen zur Verfügung", wenn der Benutzer (am Terminal) die Zeilenbearbeitung beendet hat und ein Zeilenbegrenzungszeichen sendet . Zeilentrennzeichen sind Sonderzeichen und das Ende der Datei , das Zeilenende und der Zeilenvorschub (ASCII LF ). Die beiden ersteren sind programmgesteuert einstellbar, während die letztere festgelegt ist. Die beiden letzteren sind im Zeilenbearbeitungspuffer enthalten, der erstere nicht.

Streng genommen werden null oder mehr Zeilen im Zeilenbearbeitungspuffer akkumuliert, die durch Zeilenbegrenzer getrennt sind (die read() beim Lesen möglicherweise verworfen werden oder nicht ), und die Zeilenbearbeitung wird für den Teil des Zeilenbearbeitungspuffers ausgeführt, der auf den Zeilenbearbeitungspuffer folgt letzter (falls vorhanden) Zeilenbegrenzer im Puffer. So löscht beispielsweise das Zeichen "Löschen" (was auch immer programmiert wurde) das letzte Zeichen im Zeilenpuffer nur bis zu einem vorhergehenden Zeilenbegrenzer (ohne dieses einzuschließen).

Nicht-kanonische Modusverarbeitung

Im nicht-kanonischen Modus werden Daten in einem Puffer akkumuliert (der der Zeilenbearbeitungspuffer sein kann oder nicht - einige Implementierungen haben separate Warteschlangen für "verarbeitete Eingabe" und "Roheingabe") und werden gemäß den Werten "zum Lesen verfügbar" von zwei Eingabesteuerungsparametern, den c_cc[MIN] und c_cc[TIME] Mitgliedern der termios Datenstruktur. Beide sind vorzeichenlose Mengen (da cc_t es sich um einen Alias ​​für einen vorzeichenlosen Typ handeln muss). Ersteres gibt eine Mindestanzahl von Zeichen an, und letzteres gibt eine Zeitüberschreitung in Zehntelsekunden an. Es gibt vier Möglichkeiten:

c_cc[TIME] und c_cc[MIN] sind beide Null
In diesem Fall sind die Daten im Puffer sofort "zum Lesen verfügbar" und werden read() sofort mit den Daten im Puffer zurückgegeben (möglicherweise wird Null zurückgegeben, wenn keine Daten verfügbar sind).
c_cc[TIME] ist ungleich Null und c_cc[MIN] ist Null
In diesem Fall sind die Daten im Puffer nach Ablauf des angegebenen Zeitlimits "zum Lesen verfügbar", der Timer wird durch den Start des read() Systemaufrufs ausgelöst oder wenn ein einzelnes Zeichen empfangen wird. Mit anderen Worten, read() wartet auf eine maximal festgelegte Gesamtzeit und gibt möglicherweise keine Daten zurück und gibt alle Daten zurück, sobald sie empfangen werden.
c_cc[TIME] ist Null und c_cc[MIN] ist nicht Null
In diesem Fall sind die Daten im Puffer "zum Lesen verfügbar", nachdem die angegebene Anzahl von Zeichen im Puffer empfangen wurde. Mit anderen Worten, das read() Warten auf eine Mindestdatenmenge (die möglicherweise größer ist als die, die der Anrufer im Systemaufruf lesen möchte) gibt keine Daten zurück und wartet möglicherweise auf unbestimmte Zeit.
c_cc[TIME] und c_cc[MIN] sind beide ungleich Null
In diesem Fall sind die Daten im Puffer "zum Lesen verfügbar", nachdem die angegebene Anzahl von Zeichen im Puffer empfangen wurde oder das Zeitlimit seit der Eingabe des letzten Zeichens abgelaufen ist. Es gibt keine Zeitüberschreitung für das allererste Zeichen. Mit anderen Worten, das read() Warten auf eine Mindestdatenmenge (die möglicherweise größer ist als die, die der Anrufer im Systemaufruf lesen möchte) gibt keine Nulldaten zurück, wartet möglicherweise auf unbestimmte Zeit, wartet jedoch nicht länger als das angegebene Zeitlimit wenn sich mindestens ein Zeichen im zu lesenden Puffer befindet.

Ausgabeverarbeitung

Die Ausgabeverarbeitung ist gegenüber den System III / System V-Wurzeln weitgehend unverändert. Steuerflags für den Ausgabemodus bestimmen verschiedene Optionen:

  • Wagenrücklauf kann vor jedem Zeilenvorschub - Zeichen eingefügt werden, Unix newline Semantik auf die ASCII - Semantik , dass viele Terminals erwarten zu übersetzen.
  • Terminals kann Zeit gegeben werden, um verschiedene Steuercodes auszuüben, die (auf einer Fernschreibmaschine oder ähnlichem) zu physischen Bewegungen des Wagens führen würden, die (aus Sicht des Computers) erhebliche Zeit in Anspruch nehmen können, wie z. B. Rückräume, horizontale Laschen, Wagen Rückgabe, Formularvorschübe und Zeilenvorschübe.

Anmerkungen

Quellen

Weiterführende Literatur