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.

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.
røye til streng
Terminal : Kombinasjonstastatur/videoskjerm.

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
reagere inline stil
// 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);> }> |
>
siste nøkkelord i java
>
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);> }> |
>
>
regresjonstesting i programvaretesting
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 .