Input-output system kaller i C | Opprett, Åpne, Lukk, Les, Skriv

Input-output system kaller i C | Opprett, Åpne, Lukk, Les, Skriv

Systemanrop er anropene som et program gjør til systemkjernen for å tilby tjenestene som programmet ikke har direkte tilgang til. For eksempel gi tilgang til inn- og utdataenheter som skjermer og tastaturer. Vi kan bruke ulike funksjoner i C-programmeringsspråket for inn-/utdatasystemanrop som for eksempel opprette, åpne, lese, skrive osv.

Før vi går videre til I/O-systemsamtalene, må vi vite om noen viktige termer.

Viktig terminologi

Hva er filbeskrivelsen?

Filbeskrivelsen er et heltall som unikt identifiserer en åpen fil av prosessen.

Filbeskrivelsestabell: En fil deskriptortabell er samlingen av heltallsarrayindekser som er filbeskrivelser der elementer er pekere til filtabelloppføringer. En unik filbeskrivelsestabell er gitt i operativsystemet for hver prosess.

Filtabelloppføring: Filtabelloppføringer er en struktur i minnet surrogat for en åpen fil, som opprettes når du behandler en forespørsel om å åpne filen, og disse oppføringene opprettholder filposisjonen.

Filtabelloppføring i C

Standard filbeskrivelser : Når en prosess starter, åpnes den prosessfilbeskrivelsestabellens fd(filbeskrivelse) 0, 1, 2 automatisk, (som standard) hver av disse 3 fd refererer til filtabelloppføringen for en fil som heter /dev/tty

/dev/tty : In-memory surrogat for terminalen.

Terminal : Kombinasjonstastatur/videoskjerm.

Standard filbeskrivelser

Les fra stdin => les fra fd 0 : Hver gang vi skriver et tegn fra tastaturet, leser det fra stdin til fd 0 og lagres til en fil som heter /dev/tty.
Skriv til stdout => skriv til fd 1 : Hver gang vi ser utdata til videoskjermen, er det fra filen som heter /dev/tty og skrevet til stdout på skjermen gjennom fd 1.
Skriv til stderr => skriv til fd 2 : Vi ser noen feil på videoskjermen, det er også fra den filen skrives til stderr i skjermen gjennom fd 2.

Inn-/utdatasystemanrop

I utgangspunktet er det totalt 5 typer I/O-systemanrop:

1. C opprette

Create()-funksjonen brukes til å lage en ny tom fil i C. Vi kan spesifisere tillatelsen og navnet på filen vi ønsker å lage ved å bruke create()-funksjonen. Det er definert på innsiden header-filen og flaggene som sendes som argumenter er definert inne header-fil.

Syntaks for create() i C

int   create  (char *  filename  , mode_t   mode  ); 

Parameter

  • filnavn: navnet på filen du vil lage
  • modus: indikerer tillatelser for den nye filen.

Returverdi

  • returner første ubrukte filbeskrivelse (vanligvis 3 når du først oppretter bruk i prosessen fordi 0, 1, 2 fd er reservert)
  • returner -1 når en feil

Hvordan C create() fungerer i OS

  • Opprett en ny tom fil på disken.
  • Opprett filtabelloppføring.
  • Sett den første ubrukte filbeskrivelsen til å peke på filtabelloppføringen.
  • Returfilbeskrivelse brukt, -1 ved feil.

2. C åpen

Open()-funksjonen i C brukes til å åpne filen for lesing, skriving eller begge deler. Den er også i stand til å lage filen hvis den ikke eksisterer. Det er definert på innsiden header-filen og flaggene som sendes som argumenter er definert inne header-fil.

Syntaks for open() i C

int   open   (const char*   Path  , int   flags  ); 

Parametere

  • Sti: Banen til filen vi ønsker å åpne.
    • Bruke absolutt vei begynner med / når du er ikke jobber i samme katalog som C-kildefilen.
    • Bruk relativ vei som bare er filnavnet med filtypen, når du er det jobber i samme katalog som C-kildefilen.
  • flagg: Den brukes til å spesifisere hvordan du vil åpne filen. Vi kan bruke følgende flagg.

Flagg

Beskrivelse

O_RDONLY Åpner filen i skrivebeskyttet modus.
O_FRITT Åpner filen i skrivebeskyttet modus.
O_RDWR Åpner filen i lese- og skrivemodus.
O_CREATE Opprett en fil hvis den ikke eksisterer.
O_EXCL Forhindre opprettelse hvis den allerede eksisterer.
O_ TILLEGG Åpner filen og plasserer markøren på slutten av innholdet.
O_ASYNC Aktiver inngangs- og utgangskontroll med signal.
O_CLOEXEC Aktiver close-on-exec-modus på den åpne filen.
O_NONBLOCK Deaktiverer blokkering av filen som er åpnet.
O_TMPFILE Opprett en ikke navngitt midlertidig fil på den angitte banen.

Hvordan C open() fungerer i OS

  • Finn den eksisterende filen på disken.
  • Opprett filtabelloppføring.
  • Sett den første ubrukte filbeskrivelsen til å peke på filtabelloppføringen.
  • Returfilbeskrivelse brukt, -1 ved feil.

Eksempel 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;> }>

Produksjon

fd = 3 

3. C lukk

Close()-funksjonen i C forteller operativsystemet at du er ferdig med en filbeskrivelse, og lukker filen som filbeskrivelsen peker på. Det er definert på innsiden header-fil.

Syntaks for close() i C

int close(int fd); 

Parameter

  • fd: F ile-beskrivelse for filen du vil lukke.

Returverdi

  • 0 på suksess.
  • -1 på feil.

Hvordan C close() fungerer i operativsystemet

  • Ødelegg filtabelloppføring referert av element fd i filbeskrivelsestabellen
    – Så lenge ingen annen prosess peker på det!
  • Sett element fd i filbeskrivelsestabellen til NULL

Eksempel 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. '> );> }>

Produksjon

opened the fd = 3 closed the fd. 

Eksempel 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);> }>

Produksjon

fd2 = 3 

Her, I denne koden returnerer først open() 3 fordi når hovedprosessen er opprettet, så fd 0, 1, 2 allerede er tatt av stdin , standout, og stderr . Så den første ubrukte filbeskrivelsen er 3 i filbeskrivelsestabellen. Etter det i close() systemkall er gratis det disse 3 filbeskrivelser og deretter angi 3 filbeskrivelser som null . Så når vi kalte den andre open(), så er den første ubrukte fd også 3 . Så resultatet av dette programmet er 3 .

4. C les

Fra filen angitt av filbeskrivelsen fd, leser read()-funksjonen den angitte mengden byte cnt inndata i minneområdet indikert med buff . En vellykket read() oppdaterer tilgangstiden for filen. Read()-funksjonen er også definert inne i header-filen.

Syntaks for read() i C

size_t   read   (int   fd  , void*   buf  , size_t   cnt  ); 

Parametere

  • fd: filbeskrivelse for filen som data skal leses fra.
  • buff: buffer å lese data fra
  • cnt: lengden på bufferen

Returverdi

  • return Antall byte lest ved suksess
  • returner 0 når du når slutten av filen
  • returner -1 ved feil
  • retur -1 ved signalavbrudd

Viktige poeng

  • buff må peke til en gyldig minneplassering med en lengde som ikke er mindre enn den angitte størrelsen på grunn av overløp.
  • fd bør være en gyldig filbeskrivelse returnert fra open() for å utføre leseoperasjonen fordi hvis fd er NULL, bør lesingen generere en feil.
  • cnt er det forespurte antallet leste byte, mens returverdien er det faktiske antallet leste byte. Noen ganger bør lesesystemanrop lese færre byte enn cnt.

Eksempel 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;> }>

Produksjon

called read(3, c, 10). returned that 10 bytes were read. Those bytes are as follows: 0 0 0 foo. 

Anta at foobar.txt består av de 6 ASCII-tegnene foobar. Hva er så resultatet av følgende 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);> }>

Produksjon

c = f 

Deskriptorene fd1 og fd2 hver har sin egen åpne filtabelloppføring, så hver deskriptor har sin egen filposisjon for foobar.txt . Dermed leses fra fd2 leser den første byten av foobar.txt , og utgangen er c = f , ikke c = o .

5. C skriv

Skriver cnt-bytes fra buf til filen eller kontakten som er knyttet til fd. cnt skal ikke være større enn INT_MAX (definert i limits.h header-filen). Hvis cnt er null, returnerer write() ganske enkelt 0 uten å prøve noen annen handling.

Write() er også definert inne header-fil.

Syntaks for write() i C

size_t   write   (int   fd  , void*   buf  , size_t   cnt  ); 

Parametere

  • fd: filbeskrivelse
  • buff: buffer å skrive data fra.
  • cnt: lengden på bufferen.

Returverdi

  • returnerer antall byte skrevet ved suksess.
  • returner 0 når du når slutten av filen.
  • returner -1 ved feil.
  • retur -1 på signalavbrudd.

Viktige punkter om C-skriving

  • Filen må åpnes for skriveoperasjoner
  • buff må være minst like lang som spesifisert av cnt fordi hvis buf-størrelsen er mindre enn cnt, vil buf føre til overløpstilstanden.
  • cnt er det forespurte antallet byte å skrive, mens returverdien er det faktiske antallet byte som er skrevet. Dette skjer når fd har et mindre antall byte å skrive enn cnt.
  • Hvis write() blir avbrutt av et signal, er effekten en av følgende:
    • Hvis write() ikke har skrevet noen data ennå, returnerer den -1 og setter errno til EINTR.
    • Hvis write() har skrevet noen data, returnerer den antall byte den skrev før den ble avbrutt.

Eksempel på skriv() 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);> }>

Produksjon

called write(3, 'hello geeks
', 12). it returned 11 

Her, når du ser i filen foo.txt etter å ha kjørt koden, får du en hei nerder . Hvis foo.txt-filen allerede har noe innhold i seg, vil skrive-en-systemet-anrop overskrive innholdet og alt tidligere innhold er slettet og bare hei nerder innholdet vil ha i filen.

Eksempel: Skriv ut hello world fra programmet uten å bruke noen printf-funksjon.

C




// 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;> }>

Produksjon

hello world 

I denne koden, buf1 arrays streng Hei Verden skrives først inn i stdin fd[0] og deretter skrives denne strengen inn i stdin til buf2 array. Deretter skriver du inn i buf2-arrayen til stdout og skriver ut Hei Verden .