Input-output system kalder i C | Opret, Åbn, Luk, Læs, Skriv
Systemkald er de opkald, som et program foretager til systemkernen for at levere de tjenester, som programmet ikke har direkte adgang til. For eksempel at give adgang til input- og outputenheder såsom skærme og tastaturer. Vi kan bruge forskellige funktioner i C-programmeringssproget til input/output systemopkald, såsom oprette, åbne, læse, skrive osv.
Inden vi går videre til I/O-systemopkaldene, skal vi kende til nogle få vigtige termer.
Vigtig terminologi
Hvad er filbeskrivelsen?
Filbeskrivelsen er et heltal, der unikt identificerer en åben fil i processen.
Filbeskrivelsestabel: En fil deskriptor tabel er samlingen af heltal matrix indekser, der er fil deskriptorer, hvor elementer er pointere til fil tabel poster. En unik filbeskrivelsestabel findes i operativsystemet for hver proces.
Indtastning af filtabel: Filtabelposter er en struktur i hukommelsen surrogat for en åben fil, som oprettes ved behandling af en anmodning om at åbne filen, og disse poster bevarer filpositionen.
Standard filbeskrivelser : Når en proces starter, åbner denne procesfilbeskrivelsestabels fd(filbeskrivelse) 0, 1, 2 automatisk, (som standard) hver af disse 3 fd refererer til filtabelpost for en fil med navnet /dev/tty
/dev/tty : In-memory surrogat til terminalen.
Terminal : Kombinationstastatur/videoskærm.
Læs fra stdin => læs fra fd 0 : Når vi skriver et hvilket som helst tegn fra tastaturet, læser det fra stdin til fd 0 og gemmer til en fil med navnet /dev/tty.
Skriv til stdout => skriv til fd 1 : Når vi ser noget output til videoskærmen, er det fra filen med navnet /dev/tty og skrevet til stdout på skærmen gennem fd 1.
Skriv til stderr => skriv til fd 2 : Vi ser enhver fejl på videoskærmen, det er også fra den fil at skrive til stderr på skærmen gennem fd 2.
Input/output systemopkald
Grundlæggende er der i alt 5 typer I/O-systemkald:
1. C oprette
Create()-funktionen bruges til at oprette en ny tom fil i C. Vi kan angive tilladelsen og navnet på den fil, som vi vil oprette ved hjælp af create()-funktionen. Det er defineret indeni header-fil og de flag, der sendes som argumenter, er defineret inde header-fil.
Syntaks for create() i C
int create (char * filename , mode_t mode );
Parameter
- filnavn: navnet på den fil, du vil oprette
- mode: angiver tilladelser til den nye fil.
Returværdi
- returner første ubrugte filbeskrivelse (generelt 3, når der først oprettes brug i processen, fordi 0, 1, 2 fd er reserveret)
- returner -1, når en fejl
Hvordan C create() virker i OS
- Opret en ny tom fil på disken.
- Opret filtabelpost.
- Indstil den første ubrugte filbeskrivelse til at pege på filtabelposten.
- Returfilbeskrivelse brugt, -1 ved fejl.
2. C åben
Open()-funktionen i C bruges til at åbne filen til læsning, skrivning eller begge dele. Det er også i stand til at oprette filen, hvis den ikke eksisterer. Det er defineret indeni header-fil og de flag, der sendes som argumenter, er defineret inde header-fil.
Syntaks for open() i C
int open (const char* Path , int flags );
Parametre
- Sti: Sti til den fil, vi vil åbne.
- Brug absolut vej begynder med / når du er ikke arbejder i samme mappe som C-kildefilen.
- Brug relativ vej som kun er filnavnet med filtypenavnet, når du er det arbejder i samme mappe som C-kildefilen.
- flag: Det bruges til at angive, hvordan du vil åbne filen. Vi kan bruge følgende flag.
| Flag | Beskrivelse |
|---|---|
| O_RDONLY | Åbner filen i skrivebeskyttet tilstand. |
| O_FORREKT | Åbner filen i skrivebeskyttet tilstand. |
| O_RDWR | Åbner filen i læse- og skrivetilstand. |
| O_CREATE | Opret en fil, hvis den ikke findes. |
| O_EXCL | Forhindre oprettelse, hvis den allerede eksisterer. |
| O_ TILFØJ | Åbner filen og placerer markøren i slutningen af indholdet. |
| O_ASYNC | Aktiver ind- og udgangsstyring via signal. |
| O_CLOEXEC | Aktiver close-on-exec-tilstand på den åbne fil. |
| O_NONBLOCK | Deaktiverer blokering af den åbnede fil. |
| O_TMPFILE | Opret en unavngiven midlertidig fil på den angivne sti. |
Hvordan C open() virker i OS
- Find den eksisterende fil på disken.
- Opret filtabelpost.
- Indstil den første ubrugte filbeskrivelse til at pege på filtabelposten.
- Returfilbeskrivelse brugt, -1 ved fejl.
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;> }> |
Produktion
fd = 3
3. C luk
Close()-funktionen i C fortæller operativsystemet, at du er færdig med en filbeskrivelse og lukker filen, som filbeskrivelsen peger på. Det er defineret indeni header-fil.
Syntaks for close() i C
int close(int fd);
Parameter
- fd: F ile-beskrivelse for den fil, du vil lukke.
Returværdi
- 0 på succes.
- -1 på fejl.
Hvordan C close() virker i OS
- Ødelæg filtabelindgang refereret af element fd i filbeskrivelsestabellen
– Så længe ingen anden proces peger på det! - Indstil element fd i filbeskrivelsestabel til NUL
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.
'> );> }> |
Produktion
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);> }> |
Produktion
fd2 = 3
Her, I denne kode returnerer først open() 3 fordi når hovedprocessen er skabt, så fd 0, 1, 2 allerede er taget af stdin , standout, og stderr . Så den første ubrugte filbeskrivelse er 3 i filbeskrivelsestabellen. Efter at i close() systemkald er gratis det disse 3 filbeskrivelser og sæt derefter 3 filbeskrivelser som nul . Så når vi kaldte den anden open(), så er den første ubrugte fd også 3 . Så resultatet af dette program er 3 .
4. C læs
Fra filen angivet af filbeskrivelsen fd, læser read()-funktionen det angivne antal bytes cnt af input i hukommelsesområdet angivet ved buf . En vellykket read() opdaterer adgangstiden for filen. Read()-funktionen er også defineret inde i header-filen.
Syntaks for read() i C
size_t read (int fd , void* buf , size_t cnt );
Parametre
- fd: filbeskrivelse af filen, hvorfra data skal læses.
- buff: buffer til at læse data fra
- cnt: længden af bufferen
Returværdi
- return Antal læste bytes ved succes
- returner 0 ved at nå slutningen af filen
- returner -1 ved fejl
- retur -1 ved signalafbrydelse
Vigtige pointer
- buf skal pege på en gyldig hukommelsesplacering med en længde, der ikke er mindre end den angivne størrelse på grund af overløb.
- fd skal være en gyldig filbeskrivelse, der returneres fra open() for at udføre læseoperationen, fordi hvis fd er NULL, så skulle læsningen generere en fejl.
- cnt er det ønskede antal læste bytes, mens returværdien er det faktiske antal læste bytes. Nogle gange bør læst systemkald også læse færre bytes end 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;> }> |
Produktion
called read(3, c, 10). returned that 10 bytes were read. Those bytes are as follows: 0 0 0 foo.
Antag, at foobar.txt består af de 6 ASCII-tegn foobar. Hvad er outputtet af 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);> }> |
Produktion
c = f
Deskriptorerne fd1 og fd2 hver har deres egen åbne filtabelpost, så hver deskriptor har sin egen filposition til foobar.txt . Således læses fra fd2 læser den første byte af foobar.txt , og outputtet er c = f , ikke c = o .
5. C skriv
Skriver cnt-bytes fra buf til filen eller socket, der er forbundet med fd. cnt bør ikke være større end INT_MAX (defineret i limits.h header-filen). Hvis cnt er nul, returnerer write() blot 0 uden at forsøge nogen anden handling.
Write() er også defineret inde header-fil.
Syntaks for write() i C
size_t write (int fd , void* buf , size_t cnt );
Parametre
- fd: filbeskrivelse
- buff: buffer til at skrive data fra.
- cnt: længden af bufferen.
Returværdi
- returnerer antallet af bytes skrevet ved succes.
- returner 0 ved at nå slutningen af filen.
- returner -1 ved fejl.
- retur -1 ved signalafbrydelser.
Vigtige punkter om C skrive
- Filen skal åbnes for skriveoperationer
- buf skal være mindst lige så lang som specificeret af cnt, fordi hvis buf-størrelsen er mindre end cnt, vil buf føre til overløbstilstanden.
- cnt er det ønskede antal bytes at skrive, mens returværdien er det faktiske antal bytes skrevet. Dette sker når fd har et mindre antal bytes at skrive end cnt.
- Hvis write() afbrydes af et signal, er effekten en af følgende:
- Hvis write() ikke har skrevet nogen data endnu, returnerer den -1 og sætter errno til EINTR.
- Hvis write() har skrevet nogle data, returnerer det antallet af bytes, det skrev, før det blev afbrudt.
Eksempel 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
Her, når du ser i filen foo.txt efter at have kørt koden, får du en hej nørder . Hvis foo.txt-filen allerede har noget indhold i sig, så overskriver skrive et system-opkald indholdet, og alt tidligere indhold er slettet og kun hej nørder indhold vil have i filen.
Eksempel: Udskriv hello world fra programmet uden at bruge nogen printf-funktion.
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;> }> |
Produktion
hello world
I denne kode, buf1 arrays streng Hej Verden skrives først ind i stdin fd[0] og derefter skrives denne streng ind i stdin til buf2 array. Skriv derefter i buf2 array til stdout og print output Hej Verden .