logo

Input-out-system anropar i C | Skapa, Öppna, Stäng, Läs, Skriv

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.

Filtabellpost i C

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.

Standardfilbeskrivningar

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 .