Systemanrop är de anrop som ett program gör till systemkärnan för att tillhandahålla de tjänster som programmet inte har direkt åtkomst till. Till exempel ge tillgång till in- och utdataenheter som monitorer och tangentbord. Vi kan använda olika funktioner som tillhandahålls i programmeringsspråket C för in-/utdatasystemanrop som skapa, öppna, läsa, skriva, etc.
Innan vi går vidare till I/O-systemsamtal måste vi känna till några viktiga termer.
Viktig terminologi
Vad är filbeskrivningen?
Filbeskrivningen är ett heltal som unikt identifierar en öppen fil i processen.
Filbeskrivningstabell: En fil deskriptortabell är samlingen av heltalsmatrisindex som är fildeskriptorer där element är pekare till filtabellposter. En unik filbeskrivningstabell tillhandahålls i operativsystemet för varje process.
Filtabellpost: Filtabellposter är en struktur i minnets surrogat för en öppen fil, som skapas när en begäran om att öppna filen behandlas och dessa poster bibehåller filpositionen.

Standardfilbeskrivningar : När någon process startar, öppnas den processfilbeskrivningstabellens fd(filbeskrivning) 0, 1, 2 automatiskt, (som standard) var och en av dessa 3 fd refererar till filtabellposten för en fil med namnet /dev/tty
/dev/tty : In-memory surrogat för terminalen.
Terminal : Kombination av tangentbord/videoskärm.

Läs från stdin => läs från fd 0 : När vi skriver något tecken från tangentbordet läser det från stdin till fd 0 och sparas till en fil som heter /dev/tty.
Skriv till stdout => skriv till fd 1 : När vi ser någon utdata till videoskärmen är den från filen som heter /dev/tty och skriven till stdout på skärmen genom fd 1.
Skriv till stderr => skriv till fd 2 : Vi ser något fel på videoskärmen, det är också från den filen att skriva till stderr på skärmen genom fd 2.
In-/utgångssystemanrop
I grund och botten finns det totalt 5 typer av I/O-systemanrop:
1. C skapa
Create()-funktionen används för att skapa en ny tom fil i C. Vi kan ange behörigheten och namnet på filen som vi vill skapa med funktionen create(). Det är definierat inuti header-filen och flaggorna som skickas som argument definieras inuti header-fil.
Syntax för create() i C
int create (char * filename , mode_t mode );>
Parameter
- filnamn: namnet på filen som du vill skapa
- läge: indikerar behörigheter för den nya filen.
Returvärde
- returnera den första oanvända filbeskrivningen (vanligtvis 3 när du först skapar användning i processen eftersom 0, 1, 2 fd är reserverade)
- returnera -1 vid ett fel
Hur C create() fungerar i OS
- Skapa en ny tom fil på disken.
- Skapa filtabellpost.
- Ställ in den första oanvända filbeskrivningen så att den pekar på filtabellposten.
- Returnera filbeskrivning som används, -1 vid fel.
2. C öppen
Open()-funktionen i C används för att öppna filen för läsning, skrivning eller båda. Det är också kapabelt att skapa filen om den inte finns. Det är definierat inuti header-filen och flaggorna som skickas som argument definieras inuti header-fil.
Syntax för open() i C
int open (const char* Path , int flags );>
Parametrar
- Väg: Sökväg till filen som vi vill öppna.
- Använd absolut väg börjar med / när du är inte arbetar i samma katalog som C-källfil.
- Använda sig av relativ väg som bara är filnamnet med filändelse, när du är det arbetar i samma katalog som C-källfil.
- flaggor: Den används för att ange hur du vill öppna filen. Vi kan använda följande flaggor.
| Flaggor | Beskrivning |
|---|---|
| O_RDONLY | Öppnar filen i skrivskyddat läge. |
| O_FULLT | Öppnar filen i skrivskyddsläge. |
| O_RDWR | Öppnar filen i läs- och skrivläge. |
| O_SKAPA | Skapa en fil om den inte finns. |
| O_EXCL | Förhindra skapandet om det redan finns. |
| O_ BILAGA | Öppnar filen och placerar markören i slutet av innehållet. |
| O_ASYNC | Aktivera in- och utgångsstyrning via signal. |
| O_CLOEXEC | Aktivera close-on-exec-läge på den öppna filen. |
| O_NONBLOCK | Inaktiverar blockering av den öppnade filen. |
| O_TMPFILE | Skapa en icke namngiven temporär fil på den angivna sökvägen. |
Hur C open() fungerar i OS
- Hitta den befintliga filen på disken.
- Skapa filtabellpost.
- Ställ in den första oanvända filbeskrivningen så att den pekar på filtabellposten.
- Returnera filbeskrivning som används, -1 vid fel.
Exempel på C open()
C
// C program to illustrate> // open system call> #include> #include> #include> #include> extern> int> errno>;> int> main()> {> >// if file does not have in directory> >// then file foo.txt is created.> >int> fd = open(>'foo.txt'>, O_RDONLY | O_CREAT);> >printf>(>'fd = %d
'>, fd);> >if> (fd == -1) {> >// print which type of error have in a code> >printf>(>'Error Number % d
'>,>errno>);> >// print program detail 'Success or failure'> >perror>(>'Program'>);> >}> >return> 0;> }> |
>
>
Produktion
fd = 3>
3. C stäng
Close()-funktionen i C talar om för operativsystemet att du är klar med en filbeskrivning och stänger filen som pekas av filbeskrivningen. Det är definierat inuti header-fil.
Syntax för close() i C
int close(int fd);>
Parameter
- fd: F ile-beskrivning för filen som du vill stänga.
Returvärde
- 0 på framgång.
- -1 på fel.
Hur C close() fungerar i operativsystemet
- Förstör filtabellpost som refereras av element fd i filbeskrivningstabellen
– Så länge ingen annan process pekar på det! - Ställ in element fd i filbeskrivningstabellen till NULL
Exempel 1: close() i C
C
// C program to illustrate close system Call> #include> #include> #include> int> main()> {> >int> fd1 = open(>'foo.txt'>, O_RDONLY);> >if> (fd1 <0) {> >perror>(>'c1'>);> >exit>(1);> >}> >printf>(>'opened the fd = % d
'>, fd1);> >// Using close system Call> >if> (close(fd1) <0) {> >perror>(>'c1'>);> >exit>(1);> >}> >printf>(>'closed the fd.
'>);> }> |
>
>
Produktion
opened the fd = 3 closed the fd.>
Exempel 2:
C
// C program to illustrate close system Call> #include> #include> int> main()> {> >// assume that foo.txt is already created> >int> fd1 = open(>'foo.txt'>, O_RDONLY, 0);> >close(fd1);> > >// assume that baz.tzt is already created> >int> fd2 = open(>'baz.txt'>, O_RDONLY, 0);> > >printf>(>'fd2 = % d
'>, fd2);> >exit>(0);> }> |
>
>
Produktion
fd2 = 3>
Här, I denna kod returnerar first open() 3 för när huvudprocessen skapas, då fd 0, 1, 2 är redan tagna av stdin , stdout, och stderr . Så den första oanvända filbeskrivningen är 3 i filbeskrivningstabellen. Efter att i close() systemanrop är gratis det dessa 3 filbeskrivningar och ställ sedan in 3 filbeskrivningar som null . Så när vi anropade den andra open(), så är den första oanvända fd också 3 . Så resultatet av detta program är 3 .
4. C läs
Från filen som anges av filbeskrivningen fd, läser read()-funktionen det angivna antalet byte cnt inmatning i minnesområdet som indikeras av buff . En framgångsrik read() uppdaterar åtkomsttiden för filen. Read()-funktionen är också definierad i rubrikfilen.
Syntax för read() i C
size_t read (int fd , void* buf , size_t cnt );>
Parametrar
- fd: filbeskrivning av filen från vilken data ska läsas.
- buff: buffert att läsa data från
- cnt: buffertens längd
Returvärde
- return Antal byte lästa vid framgång
- returnera 0 när du når slutet av filen
- returnera -1 vid fel
- retur -1 vid signalavbrott
Viktiga punkter
- buff måste peka på en giltig minnesplats med en längd som inte är mindre än den angivna storleken på grund av spill.
- fd bör vara en giltig filbeskrivning som returneras från open() för att utföra läsoperationen eftersom om fd är NULL bör läsningen generera ett fel.
- cnt är det begärda antalet lästa byte, medan returvärdet är det faktiska antalet lästa byte. Vissa gånger bör också läsa systemanrop läsa färre byte än cnt.
Exempel på read() i C
C
// C program to illustrate> // read system Call> #include> #include> #include> int> main()> {> >int> fd, sz;> >char>* c = (>char>*)>calloc>(100,>sizeof>(>char>));> >fd = open(>'foo.txt'>, O_RDONLY);> >if> (fd <0) {> >perror>(>'r1'>);> >exit>(1);> >}> >sz = read(fd, c, 10);> >printf>(>'called read(% d, c, 10). returned that'> >' %d bytes were read.
'>,> >fd, sz);> >c[sz] =>' '>;> >printf>(>'Those bytes are as follows: % s
'>, c);> >return> 0;> }> |
>
>
Produktion
called read(3, c, 10). returned that 10 bytes were read. Those bytes are as follows: 0 0 0 foo.>
Anta att foobar.txt består av de 6 ASCII-tecken foobar. Vad är då resultatet av följande program?
C
// C program to illustrate> // read system Call> #include> #include> #include> #include> int> main()> {> >char> c;> >int> fd1 = open(>'sample.txt'>, O_RDONLY, 0);> >int> fd2 = open(>'sample.txt'>, O_RDONLY, 0);> >read(fd1, &c, 1);> >read(fd2, &c, 1);> >printf>(>'c = %c
'>, c);> >exit>(0);> }> |
>
>
Produktion
c = f>
Beskrivningarna fd1 och fd2 var och en har sin egen öppna filtabellpost, så varje deskriptor har sin egen filposition för foobar.txt . Alltså läser från fd2 läser den första byten av foobar.txt , och utgången är c = f , inte c = o .
5. C skriv
Skriver cnt-bytes från buf till filen eller socket som är associerad med fd. cnt bör inte vara större än INT_MAX (definierad i rubrikfilen limits.h). Om cnt är noll, returnerar write() helt enkelt 0 utan att försöka göra någon annan åtgärd.
Write() är också definierad inuti header-fil.
Syntax för write() i C
size_t write (int fd , void* buf , size_t cnt );>
Parametrar
- fd: filbeskrivning
- buff: buffert att skriva data från.
- cnt: buffertens längd.
Returvärde
- returnerar antalet byte som skrivits vid framgång.
- returnera 0 när du når slutet av filen.
- returnera -1 vid fel.
- retur -1 på signalavbrott.
Viktiga punkter om C write
- Filen måste öppnas för skrivoperationer
- buff måste vara minst så lång som specificerats av cnt eftersom om bufstorleken är mindre än cnt så kommer buf att leda till överflödestillståndet.
- cnt är det begärda antalet byte att skriva, medan returvärdet är det faktiska antalet skrivna byte. Detta händer när fd har ett mindre antal byte att skriva än cnt.
- Om write() avbryts av en signal är effekten en av följande:
- Om write() inte har skrivit någon data ännu, returnerar den -1 och sätter errno till EINTR.
- Om write() har lyckats skriva en del data, returnerar den antalet byte den skrev innan den avbröts.
Exempel på write() i C
C
// C program to illustrate> // write system Call> #include> #include> main()> {> int> sz;> int> fd = open(>'foo.txt'>, O_WRONLY | O_CREAT | O_TRUNC, 0644);> if> (fd <0)> {> >perror>(>'r1'>);> >exit>(1);> }> sz = write(fd,>'hello geeks
'>,>strlen>(>'hello geeks
'>));> printf>(>'called write(% d, 'hello geeks
', %d).'> >' It returned %d
'>, fd,>strlen>(>'hello geeks
'>), sz);> close(fd);> }> |
>
>
Produktion
called write(3, 'hello geeks ', 12). it returned 11>
Här, när du ser i filen foo.txt efter att ha kört koden, får du en hej nördar . Om foo.txt-filen redan har en del innehåll i den så skriver ett systemanrop över innehållet och allt tidigare innehåll är raderade och bara hej nördar innehållet kommer att ha i filen.
Exempel: Skriv ut hello world från programmet utan att använda någon printf-funktion.
C
förbeställ genomgång
// C program to illustrate> // I/O system Calls> #include> #include> #include> #include> int> main(>void>)> {> >int> fd[2];> >char> buf1[12] =>'hello world'>;> >char> buf2[12];> >// assume foobar.txt is already created> >fd[0] = open(>'foobar.txt'>, O_RDWR);> >fd[1] = open(>'foobar.txt'>, O_RDWR);> >write(fd[0], buf1,>strlen>(buf1));> >write(1, buf2, read(fd[1], buf2, 12));> >close(fd[0]);> >close(fd[1]);> >return> 0;> }> |
>
>
Produktion
hello world>
I den här koden, buf1 arrays sträng Hej världen skrivs först i stdin fd[0] och därefter skrivs den här strängen in i stdin till buf2-matrisen. Skriv sedan in i buf2-arrayen till stdout och skriv ut Hej världen .