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:
- seriella enheter anslutna via en seriell port såsom skrivare / fjärrskrivare , fjärrskrivare , modem som stöder fjärrterminaler via uppringd åtkomst och direktanslutna lokala terminaler
- bildskärmsadapter och tangentbordshårdvara direkt inbyggd i systemenheten, sammantagna för att bilda en lokal "konsol", som kan presenteras för användare och för program som en enda CRT-terminal eller som flera virtuella terminaler
- mjukvaruterminalemulatorer , som xterm , Konsole , GNOME Terminal och Terminal -programmen, och nätverksservrar som rlogin -demonen och SSH -demonen , som använder pseudoterminaler
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 inxterm
som terminaltyp, till exempel. GNU Screen -programmet ställer inskä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
ochEM
) orsakade genereringen av en nySIGTSTP
-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
ochDC2
) 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 systemanropetwrite()
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
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]
ochc_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 ochc_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 ochc_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]
ochc_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
- Afzal, Amir (2008). UNIX unbounded: a beginning approach (5:e upplagan). Prentice Hall. ISBN 978-0-13-119449-6 .
- Bourne, Stephen R. (1983). UNIX-systemet . Internationell datavetenskapsserie. Addison-Wesley. ISBN 978-0-201-13791-0 .
- Christian, Kaare (1988). UNIX-operativsystemet (andra upplagan). John Wiley & Sons. ISBN 978-0-471-84781-6 .
- Kista, Stephen (1991). UNIX system V release 4: den fullständiga referensen . Osborne McGraw-Hill. ISBN 978-0-07-881653-6 .
- Frisch, Æleen (2002). Viktig systemadministration . En nötskalshandbok (3:e upplagan). O'Reilly Media, Inc. ISBN 978-0-596-00343-2 .
- Leffler, Samuel J.; McKusick, Marshall Kirk ; Karels, Michael J.; Quarterman, John S. (1989). "Terminalhantering". Utformningen och implementeringen av operativsystemet 4.3BSD UNIX . Addison-Wesley-serien i datavetenskap. Addison-Wesley. ISBN 978-0-201-06196-3 .
- Zlotnick, Fred (1991). "Styra terminalenheter". POSIX.1-standarden: en programmerares guide . Benjamin/Cummings Pub. Co. ISBN 978-0-8053-9605-8 .
Vidare läsning
- "11. Allmänt terminalgränssnitt" . Specifikationerna för öppen gruppbas . 6. Den öppna gruppen . 2004.
- Lewine, Donald A. (1991). "Terminal I/O". POSIX programmerares guide: skriva bärbara UNIX-program med POSIX.1-standarden . Datavetenskap serien. O'Reilly Media, Inc. ISBN 978-0-937175-73-6 .