POSIX terminalgränssnitt

POSIX -terminalgränssnittet är den generaliserade abstraktionen, som omfattar både ett applikationsprogrammeringsgränssnitt för program och en uppsättning beteendeförväntningar för användare av en terminal , enligt definitionen av POSIX -standarden och Single Unix-specifikationen . Det är en historisk utveckling från terminalgränssnitten i BSD version 4 och Seventh Edition Unix .

Allmänna underliggande begrepp

Hårdvara

Ett flertal I/O-enheter betraktas som "terminaler" i Unix-system. Dessa inkluderar:

Terminalintelligens och kapacitet

Intelligens: terminaler är dumma, inte intelligenta

Till skillnad från sina stordatorer och minidatorer, utvecklades idag . det ursprungliga Unix-systemet enbart för dumma terminaler, och det är fortfarande fallet En terminal är en teckenorienterad enhet, innefattande strömmar av tecken som tas emot från och skickas till enheten. Även om teckenströmmarna är strukturerade och innehåller kontrolltecken , escape-koder och specialtecken, är I/O-protokollet inte strukturerat som det skulle vara I/O-protokollet för smarta eller intelligenta terminaler. Det finns inga fältformatspecifikationer. Det finns ingen blocköverföring av hela skärmar (inmatningsformer) av indata.

Däremot använder stordatorer och minidatorer i slutna arkitekturer vanligtvis blockorienterade terminaler .

Förmåga: terminfo, termcap, curses, et al.

En terminals "förmåga" omfattar olika dumma terminalfunktioner som är utöver vad som är tillgängligt från en ren teleskrivmaskin, som program kan använda sig av. De består (huvudsakligen) av escape-koder som kan skickas till eller tas emot från terminalen. Escape-koderna som skickas till terminalen utför olika funktioner som en CRT-terminal (eller mjukvaruterminalemulator) kan som en teleskrivmaskin inte kan, som att flytta terminalens markör till positioner på skärmen, rensa och rulla hela eller delar av skärmen , slå på och stänga av anslutna skrivarenheter, programmerbara funktionstangenter, ändra skärmfärger och attribut (som omvänd video ) och ställa in skärmtitelsträngar. Escape-koderna som tas emot från terminalen betecknar saker som funktionstangent , piltangent och andra speciella tangenttryckningar ( hemknapp , slutknapp , hjälpknapp , PgUp-knapp , PgDn-knapp , infogningstangent , raderingsknapp och så vidare).

Dessa funktioner är kodade i databaser som är konfigurerade av en systemadministratör och nås från program via terminfo -biblioteket (som ersätter det äldre termcap- biblioteket), på vilket i sin tur är byggda bibliotek som curses och ncurses -biblioteken. Applikationsprogram använder terminalfunktionerna för att tillhandahålla textanvändargränssnitt med fönster, dialogrutor, knappar, etiketter, inmatningsfält, menyer och så vidare.

Kontroll av miljövariabler: TERM et al.

Den speciella uppsättning möjligheter för terminalen som ett (terminalmedvetet) programs in- och utdata använder erhålls från databasen snarare än ansluten till program och bibliotek, och styrs av miljövariabeln TERM (och, valfritt för termcap och terminfo bibliotek, miljövariablerna TERMCAP och TERMINFO ). Denna variabel ställs in av vilket terminalövervakarprogram som helst som skapar programmen som sedan använder den terminalen för dess inmatning och utmatning, eller ibland explicit. Till exempel:

  • Getty - programmet (eller motsvarande) ställer in miljövariabeln TERM enligt en systemdatabas (oftast inittab eller konfigurationsfilerna för ttymon eller lanserade program) som definierar vilka lokala terminaler som är kopplade till vilka serieportar och vilka terminaltyper som tillhandahålls av lokala virtuella terminaler eller den lokala systemkonsolen.
  • En uppringd användare på en fjärrterminal använder inte den typ av terminal som systemet vanligtvis förväntar sig på den uppringda linjen, och ställer därför manuellt in miljövariabeln TERM direkt efter inloggning till rätt typ. (Vanligtvis stämmer den terminaltyp som ställts in av getty-programmet för uppringningslinjen, som systemadministratören har bestämt ska användas oftast av uppringda användare med fjärrterminaler, den som används av uppringd användare och den användaren behöver inte åsidosätta terminaltypen.)
  • SSH - serverdemonen (eller motsvarande som rlogin -demonen) ställer in miljövariabeln TERM till samma terminaltyp som SSH-klienten.
  • Programvaruterminalemulatorn, med hjälp av en pseudoterminal, ställer in miljövariabeln TERM för att specificera typen av terminal som den emulerar. Emulerade terminaler överensstämmer ofta inte exakt med verklig terminalhårdvara, och terminalemulatorer har typnamn dedikerade för deras användning. Xterm-programmet (som standard) ställer in xterm som terminaltyp, till exempel. GNU Screen -programmet ställer in skärmen som terminaltyp.

Jobbkontroll

Terminaler ger möjlighet till jobbkontroll. Interaktivt kan användaren vid terminalen skicka kontrolltecken som avbryter det aktuella jobbet, återgå till det interaktiva jobbkontrollskalet som skapade jobbet, och kan köra kommandon som placerar jobb i "bakgrunden" eller som växlar ett annat, bakgrund, jobb i förgrunden (avhänga den vid behov).

Linjediscipliner

Strängt taget, i Unixes består en terminalenhet av den underliggande tty-enhetsdrivrutinen , ansvarig för den fysiska kontrollen av enhetens hårdvara via I/O-instruktioner och hantering av enhetsavbrottsbegäranden för teckeninmatning och -utmatning, och linjedisciplinen . En linjedisciplin är oberoende av den faktiska enhetens hårdvara, och samma linjedisciplin kan användas för en terminalkoncentratorenhet som ansvarar för flera styrande terminaler som för en pseudoterminal. Faktum är att linjedisciplinen (eller, i fallet med BSD, AIX och andra system, linjediscipliner ) är densamma för alla terminalenheter. Det är linjedisciplinen som ansvarar för lokalt eko, linjeredigering, bearbetning av inmatningslägen, bearbetning av utgångslägen och teckenmappning. Alla dessa saker är oberoende av den faktiska hårdvaran, som de gör i de enkla abstraktioner som tillhandahålls av tty enhetsdrivrutiner: överför ett tecken, ta emot ett tecken, ställ in olika hårdvarutillstånd.

I sjunde utgåvan av Unix , BSD -system och derivat inklusive macOS och Linux , kan varje terminalenhet växlas mellan flera linjediscipliner. I AT&T STREAMS -systemet är linjediscipliner STREAMS-moduler som kan skjutas in på och hoppa av en STREAMS I/O-stack.

Historia

POSIX-terminalgränssnittet härleds från terminalgränssnitten i olika Unix-system.

Early Unixes: Seventh Edition Unix

Terminalgränssnittet som tillhandahålls av Unix 32V och Seventh Edition Unix, och även presenterat av BSD version 4 som den gamla terminaldrivrutinen , var enkelt, till stor del inriktat på teleskrivmaskiner som terminaler. Indata matades in en rad i taget, med terminaldrivrutinen i operativsystemet (och inte själva terminalerna) som ger enkla radredigeringsmöjligheter. En buffert upprätthölls av kärnan där redigeringen ägde rum. Applikationer som läser terminalinmatning skulle ta emot innehållet i bufferten endast när returtangenten trycktes på terminalen för att avsluta radredigering. @ -tangenten som skickades från terminalen till systemet skulle radera ("döda") hela det aktuella innehållet i redigeringsbufferten och skulle normalt visas som en ' @ '-symbol följt av en nyradssekvens för att flytta utskriftspositionen till en ny blank linje. # -tangenten som skickades från terminalen till systemet skulle radera det sista tecknet från slutet av redigeringsbufferten och skulle normalt visas som en ' # '-symbol, som användarna måste känna igen som betecknar en "rubout" av föregående tecken (fjärrskrivmaskiner som inte fysiskt kan radera tecken när de väl har skrivits ut på papperet).

Ur programmeringssynpunkt hade en terminalenhet sändnings- och mottagningshastigheter , "radera" och "döda"-tecken (som utförde radredigering, som förklarats), "avbrott" och "avslut"-tecken (genererar signaler till alla processer för vilka terminalen var en kontrollerande terminal), "start" och "stopp"-tecken (används för modemflödeskontroll ), ett "filslut"-tecken (fungerar som en vagnretur förutom att kasseras från bufferten av read( ) systemanrop och därför potentiellt orsaka att ett resultat av noll längd returneras) och olika baslägesflaggor som avgör om lokalt eko emulerades av kärnans terminaldrivrutin, om modemflödeskontroll var aktiverad, längderna på olika utmatningsfördröjningar, mappning för vagnen returtecken och de tre inmatningslägena.

De tre inmatningslägena var:

linjeläge (även kallat "tillagat" läge)

I linjeläge utför linjedisciplinen alla radredigeringsfunktioner och känner igen "avbryta" och "avsluta" kontrolltecken och omvandlar dem till signaler som skickas till processer. Applikationsprogram som läser från terminalen får hela rader, efter att radredigering har slutförts genom att användaren trycker på retur.

cbreak-läge

cbreak-läget är ett av två tecken-i-gång-lägen. ( Stephen R. Bourne hänvisade skämtsamt till det ( Bourne 1983 , s. 288) som ett "halvkokt" och därför "sällsynt" läge.) Linjedisciplinen utför ingen radredigering, och kontrollsekvenserna för radredigeringsfunktioner behandlas som normal teckeninmatning. Applikationsprogram som läser från terminalen får tecken omedelbart, så snart de är tillgängliga i ingångskön för att läsas. Emellertid hanteras "avbryta" och "avsluta" kontrolltecken, såväl som modemflödeskontrolltecken, fortfarande speciellt och tas bort från ingångsströmmen.

råläge
råläge är det andra av de två tecken-i-åt-gång-lägena. Linjedisciplinen utför ingen radredigering, och kontrollsekvenserna för både radredigeringsfunktioner och de olika specialtecknen ("avbryta", "avsluta" och flödeskontroll) behandlas som normal teckeninmatning. Programprogram som läser från terminalen får tecken omedelbart och tar emot hela teckenströmmen oförändrad, precis som den kom från själva terminalenheten.

Det programmatiska gränssnittet för att fråga och modifiera alla dessa lägen och kontrolltecken var ioctl()- systemanropet . (Detta ersatte stty()- och gtty()- systemanropen i sjätte upplagan av Unix.) Även om tecknen "radera" och "döda" var modifierbara från deras standardvärden # och @ , var de under många år de förinställda standardinställningarna i terminalenhetsdrivrutinerna och på många Unix-system, som endast ändrade terminalenhetsinställningar som en del av inloggningsprocessen, i systeminloggningsskript som kördes efter att användaren hade angett användarnamn och lösenord, måste eventuella misstag vid inloggnings- och lösenordsprompterna korrigeras med hjälp av de historiska redigeringsnyckeltecken som ärvts från teleskrivmaskinsterminaler.

BSD: tillkomsten av jobbkontroll

Med BSD Unixes kom jobbkontroll och en ny terminaldrivrutin med utökade möjligheter. Dessa tillägg bestod av ytterligare (återigen programmässigt modifierbara) specialtecken:

  • Tecknen "suspend" och "delayed suspend" (som standard Control + Z och Control + Y — ASCII SUB och EM ) orsakade genereringen av en ny SIGTSTP -signal till processer i terminalens styrande processgrupp.
  • Tecknen "ordradering", "bokstavligen nästa" och "skriv ut igen" (som standard Control + W , Control + V och Control + R — ASCII ETB , SYN och DC2 ) utförde ytterligare radredigeringsfunktioner. "ord radera" raderade det sista ordet i slutet av radredigeringsbufferten. "literal next" gjorde det möjligt för alla specialtecken att skrivas in i radredigeringsbufferten (en funktion tillgänglig, något obekvämt, i Seventh Edition Unix via omvänt snedstreck). "reprint" fick linjedisciplinen att skriva om det aktuella innehållet i radredigeringsbufferten på en ny rad (användbart när en annan, bakgrundsprocess hade genererat utdata som hade blandat sig med radredigering).

Det programmatiska gränssnittet för att fråga och modifiera alla dessa extra lägen och kontrolltecken var fortfarande ioctl()- systemanropet, som dess skapare ( Leffler et al. 1989 , s. 262) beskrev som ett "ganska rörigt gränssnitt". All den ursprungliga Unix-funktionaliteten i sjunde upplagan behölls, och den nya funktionaliteten lades till via ytterligare ioctl()- operationskoder, vilket resulterade i ett programmatiskt gränssnitt som tydligt hade vuxit, och som presenterade en viss dubblering av funktionalitet.

System III och System V

System III introducerade ett nytt programmeringsgränssnitt som kombinerade Seventh Editions separata ioctl() -operationer för att hämta och ställa in flaggor och för att hämta och sätta kontrolltecken i anrop som använde en termiostruktur för att hålla både flaggor och kontrolltecken och som kunde få dem i en enda operation och ställ in dem i en annan enstaka operation. Den delade också upp några av flaggorna från gränssnittet i den sjunde upplagan i flera separata flaggor och lade till några ytterligare funktioner, även om den inte stödde jobbkontroll eller förbättringarna i kokt läge i 4BSD. Till exempel ersatte den "kokta", "cbreak" och "rå" lägena i sjunde upplagan med olika abstraktioner. Identifieringen av signalgenererande tecken är oberoende av ingångsläget, och det finns bara de två inmatningslägena: kanoniskt och icke-kanoniskt. (Detta tillåter ett terminalingångsläge som inte finns i Seventh Edition och BSD: kanoniskt läge med signalgenerering inaktiverad.)

System III:s efterföljare, inklusive System V , använde samma gränssnitt.

POSIX: Konsolidering och abstraktion

Ett av de stora problemen som POSIX-standarden åtgärdade med sin definition av ett allmänt terminalgränssnitt var uppsjön av programmatiska gränssnitt. Även om terminalernas beteende vid tidpunkten för standarden var ganska enhetligt från system till system, var de flesta Unix-enheter efter att ha anammat begreppen linjediscipliner och BSD-jobbkontrollfunktioner, det programmatiska gränssnittet till terminaler via ioctl()-systemanropet en enda röra . Olika Unixar tillhandahöll olika ioctl() -operationer, med olika (symboliska) namn och olika flaggor. Bärbar källkod var tvungen att innehålla en betydande mängd villkorlig kompilering för att tillgodose skillnaderna mellan programvaruplattformar, även om de alla var teoretiskt Unix.

POSIX-standarden ersätter ioctl()- systemet helt och hållet, med en uppsättning biblioteksfunktioner (som naturligtvis kan implementeras under täcket via plattformsspecifika ioctl()- operationer) med standardiserade namn och parametrar. Termiodatastrukturen för System V Unix användes som en mall för POSIX termios- datastrukturen, vars fält var i stort sett oförändrade förutom att de nu använde aliasdatatyper för att specificera fälten, vilket gjorde att de enkelt kunde porteras över flera processorarkitekturer av implementörer , snarare än att uttryckligen kräva de osignerade korta och char -datatyperna för programmeringsspråken C och C++ (vilket kan vara obekväma storlekar på vissa processorarkitekturer).

POSIX introducerade också stöd för jobbkontroll, med termios -strukturen som innehåller suspend- och delayed-suspend-tecken utöver de kontrolltecken som stöds av System III och System V. Den lade inte till några av tilläggen i kokt läge från BSD, även om SunOS 4 .x, System V Release 4 , Solaris , HP-UX , AIX , nyare BSD, macOS och Linux har implementerat dem som tillägg till termios .

Vad standarden definierar

Styra terminaler och processgrupper

Varje process i systemet har antingen en enda styrterminal eller ingen styrterminal alls. En process ärver sin styrande terminal från sin förälder, och de enda operationerna på en process är att förvärva en styrande terminal, genom en process som inte har någon styrande terminal, och avstå från den, genom en process som har en styrande terminal.

Inget portabelt sätt att skaffa en styrande terminal är definierat, metoden är implementeringsdefinierad. Standarden definierar O_NOCTTY för systemanropet open() , vilket är sättet att förhindra vad som annars är det konventionella sättet att skaffa en styrande terminal (en process utan styrande terminal open() en terminalenhetsfil som inte redan är den styrande terminalen för någon annan process, utan att specificera O_NOCTTY -flaggan) men lämnar dess konventionella semantik valfri.

Varje process är också medlem i en processgrupp. Varje terminalenhet registrerar en processgrupp som kallas dess förgrundsprocessgrupp . Processgrupperna styr terminalåtkomst och signalleverans. Signaler som genereras vid terminalen skickas till alla processer som är medlemmar i terminalens förgrundsprocessgrupp. read() och write() I/O-operationer på en terminal av en process som inte är medlem i terminalens förgrundsprocessgrupp kommer och kan valfritt (respektive) orsaka att signaler ( SIGTTIN respektive SIGTTOU ) skickas till den anropande processen . Olika terminallägesförändrande biblioteksfunktioner har samma beteende som write() , förutom att de alltid genererar signalerna, även om den funktionen är avstängd för själva write() .

Termios datastruktur _

Datastrukturen som används av alla terminalbiblioteksanrop är termios -strukturen, vars C och C++ programmeringsspråksdefinition är som följer:

  
        
        
        
        
         
  struct  termios  {  tcflag_t  c_iflag  ;  // Inmatningslägen  tcflag_t  c_oflag  ;  // Utdatalägen  tcflag_t  c_cflag  ;  // Kontrolllägen  tcflag_t  c_lflag  ;  // Lokala lägen  cc_t  c_cc  [  NCCS  ]  ;  // Kontrolltecken  }  ; 

Ordningen på fälten inom termios -strukturen är inte definierad, och implementeringar är tillåtna att lägga till icke-standardiserade fält. I själva verket måste implementeringar lägga till icke-standardiserade fält för att registrera in- och utdataöverföringshastigheter. Dessa registreras i strukturen, i en implementeringsdefinierad form, och nås via accessorfunktioner, snarare än genom direkt manipulering av fältvärdena, vilket är fallet för de standardiserade strukturfälten.

Datatypaliasen tcflag_t och cc_t , såväl som den symboliska konstanten NCCS och symboliska konstanter för de olika modflaggorna, kontrollteckennamnen och baudhastigheterna, är alla definierade i en standardheader termios.h . (Detta ska inte förväxlas med den liknande namngivna rubriken termio.h från System III och System V, som definierar en liknande termiostruktur och många liknande namngivna symboliska konstanter. Detta gränssnitt är specifikt för System III och System V, och kod som använder den kommer inte nödvändigtvis att vara portabel till andra system.)

Strukturens fält är (i sammanfattning, se huvudartikeln för detaljer [ förtydligande behövs ]) :

c_iflag
ingångslägesflaggor för kontroll av ingångsparitet, ingångsöversättning av nyradslinje, modemflödeskontroll , 8 -bitars renhet och svar på en (serieports) " break"-tillstånd
c_oflag
utmatningslägesflaggor för kontroll av implementeringsdefinierad efterbearbetning av utdata, utmatning av nyradsöversättning, och utmatningsfördröjningar efter att olika kontrolltecken har skickats
c_cflag
terminal hårdvarukontrollflaggor för att styra den faktiska terminalanordningen snarare än linjedisciplinen: antalet bitar i ett tecken, paritetstyp, avslutningskontroll och seriell linjeflödeskontroll c_lflag
lokala
kontrollflaggor för att styra linjedisciplinen snarare än terminalhårdvaran: kanoniskt läge, ekolägen, signalgenererande teckenigenkänning och hantering, och möjliggöra generering av SIGTTOU -signalen genom systemanropet write()

Bibliotekets funktioner är (i sammanfattning, se huvudartikeln för detaljer [ förtydligande behövs ]) :

.
_ _ _
_
_ _ _
_
_ implementeringsdefinierade fält i en termiosstruktur cfsetospeed
cfgetospeed()
frågar utdataöverföringshastigheten från de implementeringsdefinierade fälten i en termiosstruktur cfsetispeed
()
() ställer ställer in indataöverföringshastigheten i de implementeringsdefinierade fälten i en termiosstruktur
in
utdata överföringshastighet i de implementeringsdefinierade fälten i en termiosstruktur tcsendbreak
()
skickar en modem "break"-signal på en seriell enhetsterminal
tcdrain()
vänta på köutgång för att tömma
tcflush()
förkasta köingång
tcflow()
ändra flödeskontroll
tcgetpgrp( )
fråga terminalens förgrundsprocessgrupp
tcsetpgrp()
ställ in terminalens förgrundsprocessgrupp

Speciella karaktärer

Programmatiskt modifierbara specialtecken
Fält menande Hämtad av read() Anteckningar
c_cc[VEOF] slutet av filen Nej Bearbetas endast av radredigering i kanoniskt läge
c_cc[VEOL] slutet av raden Ja Bearbetas endast av radredigering i kanoniskt läge
c_cc[VERASE] "radera" Nej Bearbetas endast av radredigering i kanoniskt läge
c_cc[VKILL] "döda" Nej Bearbetas endast av radredigering i kanoniskt läge
c_cc[VINTR] "avbryta" Nej Signalgenererande karaktär oberoende av ingångsläge
c_cc[VQUIT] "sluta med" Nej Signalgenererande karaktär oberoende av ingångsläge
c_cc[VSUSP] "uppskjuta" Nej Signalgenererande karaktär oberoende av ingångsläge
c_cc[VSTOP] "sluta" Nej Modemflödeskontrollkaraktär oberoende av ingångsläge
c_cc[VSTART] "Start" Nej Modemflödeskontrollkaraktär oberoende av ingångsläge

Arraymedlemmen c_cc[] i termios datastruktur specificerar alla (programmässigt modifierbara) specialtecken. Indexen i arrayen är symboliska konstanter, en för varje specialteckentyp, som i tabellen till höger. (Två ytterligare poster i arrayen är relevanta för bearbetning av icke-kanoniskt läge och diskuteras nedan.)

Icke-programmatiskt modifierbara specialtecken är radmatning (ASCII LF ) och vagnretur (ASCII CR ).

Ingångsbearbetning

Indatabehandling bestämmer beteendet hos read()- systemanropet på en terminalenhet och linjeredigerings- och signalgenereringsegenskaperna för linjedisciplinen. Till skillnad från fallet med Seventh Edition Unix och BSD version 4, och som fallet med System III och System V, fungerar radredigering i ett av bara två lägen: kanoniskt läge och icke-kanoniskt läge. Den grundläggande skillnaden mellan dem är när, ur synvinkeln av blockerande/icke-blockerande krav för read()- systemanropet (specificerat med O_NONBLOCK -flaggan på fildeskriptorn via open() eller fcntl() ), data " finns att läsa".

Bearbetning i kanoniskt läge

I kanoniskt läge ackumuleras data i en radredigeringsbuffert och blir inte "tillgänglig för läsning" förrän radredigering har avslutats genom att användaren (vid terminalen) skickar ett radavgränsartecken . Radavgränsare är specialtecken och de är slutet på filen , radslutet och radmatningen (ASCII LF ). De två förstnämnda är inställbara programmatiskt, medan de senare är fixerade. De två sistnämnda ingår i radredigeringsbufferten, medan den förra inte är det.

Mer strikt, noll eller fler rader ackumuleras i radredigeringsbufferten, åtskilda av radavgränsare (som kan eller inte kan kasseras när read() kommer runt för att läsa dem), och radredigering fungerar på den del av radredigeringsbufferten som följer den sista (om någon) radavgränsaren i bufferten. Så, till exempel, "radera"-tecknet (vad det än har programmerats att vara) kommer att radera det sista tecknet i radbufferten endast upp till (men inte inklusive) en föregående radavgränsare.

Bearbetning i icke-kanoniskt läge

I icke-kanoniskt läge ackumuleras data i en buffert (som kan eller inte kan vara radredigeringsbufferten — vissa implementeringar har separata "bearbetade indata"- och "rå input"-köer) och blir "tillgänglig för läsning" enligt värdena av två ingångskontrollparametrar, c_cc[MIN] och c_cc[TIME] medlemmarna av termios datastruktur. Båda är osignerade kvantiteter (eftersom cc_t måste vara ett alias för en osignerad typ). Den förra anger ett minsta antal tecken, och den senare anger en timeout på tiondels sekund. Det finns fyra möjligheter:

c_cc[TIME] och c_cc[MIN] är båda noll
. I detta fall är data i bufferten "tillgängliga för läsning" omedelbart, och read() returnerar omedelbart med vilken data som helst i bufferten (potentiellt returnerar noll om det finns noll tillgängliga data).
c_cc[TIME] är icke-noll och c_cc[MIN] är noll
. I detta fall är data i bufferten "tillgängliga för läsning" efter att den angivna timeouten har löpt ut, och timern utlöses av starten av read() - systemet samtal, eller om ett enstaka tecken tas emot. Med andra ord, read() väntar på en maximal specificerad total tid och kan returnera noll data och returnerar all data så snart de tas emot.
c_cc[TIME] är noll och c_cc[MIN] är icke-noll.
I detta fall är data i bufferten "tillgängliga för läsning" efter att det angivna antalet tecken har tagits emot i bufferten. Med andra ord, read() väntar på en minsta mängd data (som kan vara större än vad den som ringer är beredd att läsa i systemanropet), kommer inte att returnera noll data och kan vänta på obestämd tid.
c_cc[TIME] och c_cc[MIN] är båda icke-noll.
I det här fallet är data i bufferten "tillgängliga för läsning" efter det angivna antalet tecken har tagits emot i bufferten eller timeouten har löpt ut sedan det sista tecknet angavs. Det finns ingen timeout för den allra första karaktären. Med andra ord, read() väntar på en minsta mängd data (som kan vara större än vad den som ringer är beredd att läsa i systemanropet), returnerar inte noll data, kan vänta på obestämd tid, men väntar inte längre än den angivna timeouten om minst ett tecken finns i bufferten som ska läsas.

Utdatabearbetning

Utdatabehandlingen är i stort sett oförändrad från dess System III/System V-rötter. Utmatningslägeskontrollflaggor bestämmer olika alternativ:

  • Vagnereturer kan infogas före varje radmatningstecken, för att översätta Unix newline-semantik till den ASCII-semantik som många terminaler förväntar sig.
  • Terminaler kan få tid att utöva olika kontrollkoder som (på en teleskrivmaskin eller liknande) skulle resultera i fysiska rörelser av vagnen som kan ta betydande (ur datorns synvinkel) lång tid, såsom backsteg, horisontella flikar, vagn returer, formulärmatningar och radmatningar.

Anteckningar

Källor

Vidare läsning