Vstupno-výstupné systémové volania v C | Vytvárať, otvárať, zatvárať, čítať, písať

Vstupno-výstupné systémové volania v C | Vytvárať, otvárať, zatvárať, čítať, písať

Systémové volania sú volania, ktoré program uskutočňuje do jadra systému, aby poskytoval služby, ku ktorým program nemá priamy prístup. Napríklad poskytovanie prístupu k vstupným a výstupným zariadeniam, ako sú monitory a klávesnice. Môžeme použiť rôzne funkcie poskytované v programovacom jazyku C pre vstupné/výstupné systémové volania, ako je vytvorenie, otvorenie, čítanie, zápis atď.

Predtým, ako prejdeme k I/O systémovým volaniam, musíme vedieť o niekoľkých dôležitých pojmoch.

Dôležitá terminológia

Čo je deskriptor súboru?

Deskriptor súboru je celé číslo, ktoré jednoznačne identifikuje otvorený súbor procesu.

Tabuľka deskriptora súboru: Súbor tabuľka deskriptorov je kolekcia indexov celočíselného poľa, ktoré sú deskriptormi súborov, v ktorých prvky sú ukazovatele na položky tabuľky súborov. Pre každý proces je v operačnom systéme poskytnutá jedna jedinečná tabuľka deskriptorov súborov.

Vstup do tabuľky súborov: Položky tabuľky súborov sú náhradou štruktúry v pamäti pre otvorený súbor, ktorá sa vytvorí pri spracovaní požiadavky na otvorenie súboru a tieto položky udržia pozíciu súboru.

Záznam tabuľky súborov v C

Štandardné deskriptory súborov : Keď sa spustí akýkoľvek proces, potom sa automaticky otvorí tabuľka deskriptorov súboru procesu fd (deskriptor súboru) 0, 1, 2 (štandardne) každý z týchto 3 fd odkazuje na položku tabuľky súborov pre súbor s názvom /dev/tty

/dev/tty : Náhrada terminálu v pamäti.

Terminál : Kombinovaná klávesnica/obrazovka videa.

Štandardné deskriptory súborov

Čítať z stdin => čítať z fd 0 : Kedykoľvek napíšeme akýkoľvek znak z klávesnice, prečíta sa od stdin po fd 0 a uloží sa do súboru s názvom /dev/tty.
Zápis do stdout => zápis do fd 1 : Kedykoľvek vidíme akýkoľvek výstup na obrazovku videa, pochádza zo súboru s názvom /dev/tty a zapisuje sa do stdout na obrazovke cez fd 1.
Zápis do stderr => zápis do fd 2 : Vidíme akúkoľvek chybu na obrazovke videa, je to tiež z tohto súboru zapisovať do stderr na obrazovke cez fd 2.

Vstupné/výstupné systémové volania

V zásade existuje celkom 5 typov I/O systémových volaní:

1. C vytvorte

Funkcia create() slúži na vytvorenie nového prázdneho súboru v C. Pomocou funkcie create() môžeme určiť oprávnenie a názov súboru, ktorý chceme vytvoriť. Je definovaný vo vnútri hlavičkového súboru a v ňom sú definované príznaky, ktoré sa odovzdávajú ako argumenty hlavičkový súbor.

Syntax create() v C

int   create  (char *  filename  , mode_t   mode  ); 

Parameter

  • názov súboru: názov súboru, ktorý chcete vytvoriť
  • režim: označuje povolenia nového súboru.

Návratová hodnota

  • vrátiť prvý nepoužitý deskriptor súboru (zvyčajne 3 pri prvom vytváraní použitia v procese, pretože 0, 1, 2 fd sú rezervované)
  • vrátiť -1 pri chybe

Ako funguje C create() v OS

  • Vytvorte nový prázdny súbor na disku.
  • Vytvorte záznam v tabuľke súborov.
  • Nastavte prvý nepoužitý deskriptor súboru tak, aby ukazoval na položku tabuľky súborov.
  • Vráťte použitý deskriptor súboru, -1 pri zlyhaní.

2. C otvorené

Funkcia open() v jazyku C sa používa na otvorenie súboru na čítanie, zápis alebo oboje. Je tiež schopný vytvoriť súbor, ak neexistuje. Je definovaný vo vnútri hlavičkového súboru a v ňom sú definované príznaky, ktoré sa odovzdávajú ako argumenty hlavičkový súbor.

Syntax open() v C

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

Parametre

  • cesta: Cesta k súboru, ktorý chceme otvoriť.
    • Použi absolútna cesta počnúc / keď ste nie pracujúci v rovnakom adresári ako zdrojový súbor C.
    • Použite relatívna cesta čo je iba názov súboru s príponou, ak ste pracujúci v rovnakom adresári ako zdrojový súbor C.
  • vlajky: Používa sa na určenie spôsobu, akým chcete súbor otvoriť. Môžeme použiť nasledujúce príznaky.

Vlajky

Popis

O_RDONLY Otvorí súbor v režime len na čítanie.
O_WRONLY Otvorí súbor v režime len na zápis.
O_RDWR Otvorí súbor v režime čítania a zápisu.
O_CREATE Vytvorte súbor, ak neexistuje.
O_EXCL Zabrániť vytvoreniu, ak už existuje.
O_ APPEND Otvorí súbor a umiestni kurzor na koniec obsahu.
O_ASYNC Povoliť ovládanie vstupu a výstupu signálom.
O_CLOEXEC Povoľte režim close-on-exec pre otvorený súbor.
O_NONBLOCK Zakáže blokovanie otvoreného súboru.
O_TMPFILE Vytvorte nepomenovaný dočasný súbor na zadanej ceste.

Ako funguje C open() v OS

  • Nájdite existujúci súbor na disku.
  • Vytvorte záznam v tabuľke súborov.
  • Nastavte prvý nepoužitý deskriptor súboru tak, aby ukazoval na položku tabuľky súborov.
  • Vráťte použitý deskriptor súboru, -1 pri zlyhaní.

Príklad 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;> }>

Výkon

fd = 3 

3. C zavrieť

Funkcia close() v C oznámi operačnému systému, že ste skončili s deskriptorom súboru a zatvorí súbor, na ktorý ukazuje deskriptor súboru. Je definovaný vo vnútri hlavičkový súbor.

Syntax close() v C

int close(int fd); 

Parameter

  • fd: F ile deskriptor súboru, ktorý chcete zatvoriť.

Návratová hodnota

  • 0 na úspech.
  • -1 na chybu.

Ako funguje C close() v OS

  • Zničte záznam tabuľky súborov, na ktorý odkazuje prvok fd tabuľky deskriptorov súborov
    – Pokiaľ na to nepoukazuje žiadny iný proces!
  • Nastavte prvok fd tabuľky deskriptorov súboru na NULOVÝ

Príklad 1: close() v 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. '> );> }>

Výkon

opened the fd = 3 closed the fd. 

Príklad 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);> }>

Výkon

fd2 = 3 

Tu sa v tomto kóde najprv vráti open(). 3 pretože keď sa vytvorí hlavný proces, potom fd 0, 1, 2 sú už zabraté stdin , stdout, a stderr . Takže prvý nepoužitý deskriptor súboru je 3 v tabuľke deskriptorov súborov. Potom je v close() systémové volanie zadarmo 3 deskriptory súborov a potom nastavte 3 deskriptory súborov ako nulový . Takže keď sme zavolali druhé open(), potom je aj prvé nepoužité fd 3 . Takže výstup tohto programu je 3 .

4. C čítaj

Zo súboru označeného deskriptorom súboru fd prečíta funkcia read() zadaný počet bajtov cnt vstupu do oblasti pamäte označenej symbolom buf . Úspešné čítanie () aktualizuje čas prístupu k súboru. Funkcia read() je tiež definovaná v hlavičkovom súbore.

Syntax read() v C

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

Parametre

  • fd: deskriptor súboru, z ktorého sa majú čítať údaje.
  • buf: vyrovnávacej pamäte na čítanie údajov
  • cnt: dĺžka vyrovnávacej pamäte

Návratová hodnota

  • return Počet prečítaných bajtov pri úspechu
  • vráti 0 po dosiahnutí konca súboru
  • návrat -1 pri chybe
  • návrat -1 pri prerušení signálu

Dôležité body

  • buf musí ukazovať na platné pamäťové miesto s dĺžkou nie menšou ako špecifikovaná veľkosť z dôvodu pretečenia.
  • fd by mal byť platným deskriptorom súboru vráteným z open() na vykonanie operácie čítania, pretože ak je fd NULL, čítanie by malo vygenerovať chybu.
  • cnt je požadovaný počet prečítaných bajtov, zatiaľ čo návratová hodnota je skutočný počet prečítaných bajtov. Niekedy by tiež čítanie systému malo čítať menej bajtov ako cnt.

Príklad read() v 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;> }>

Výkon

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

Predpokladajme, že foobar.txt pozostáva zo 6 ASCII znakov foobar. Aký je potom výstup nasledujúceho programu?

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

Výkon

c = f 

Deskriptory fd1 a fd2 každý má svoju vlastnú otvorenú položku tabuľky súborov, takže každý deskriptor má svoju vlastnú pozíciu súboru foobar.txt . Teda čítanie z fd2 číta prvý bajt z foobar.txt a výstupom je c = f , nie c = o .

5. C písať

Zapíše cnt bajtov z buf do súboru alebo soketu spojeného s fd. cnt by nemalo byť väčšie ako INT_MAX (definované v hlavičkovom súbore limited.h). Ak je cnt nula, write() jednoducho vráti 0 bez pokusu o inú akciu.

Write() je tiež definovaný vo vnútri hlavičkový súbor.

Syntax write() v C

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

Parametre

  • fd: deskriptor súboru
  • buf: vyrovnávacej pamäte na zapisovanie údajov.
  • cnt: dĺžka vyrovnávacej pamäte.

Návratová hodnota

  • vráti počet bajtov zapísaných pri úspechu.
  • vráti 0 po dosiahnutí konca súboru.
  • návrat -1 pri chybe.
  • návrat -1 pri prerušení signálu.

Dôležité body o zápise C

  • Pre operácie zápisu je potrebné súbor otvoriť
  • buf musí byť aspoň tak dlhý, ako je špecifikované v cnt, pretože ak je veľkosť buf menšia ako cnt, potom buf povedie k stavu pretečenia.
  • cnt je požadovaný počet bajtov na zápis, zatiaľ čo návratová hodnota je skutočný počet zapísaných bajtov. Toto sa stane, keď fd má menší počet bajtov na zápis ako cnt.
  • Ak je write() prerušený signálom, efekt je jeden z nasledujúcich:
    • Ak write() ešte nezapísala žiadne dáta, vráti -1 a nastaví errno na EINTR.
    • Ak funkcia write() úspešne zapísala nejaké údaje, vráti počet bajtov, ktoré zapísala pred prerušením.

Príklad write() v 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);> }>

Výkon

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

Tu, keď po spustení kódu uvidíte v súbore foo.txt, dostanete a ahojte geekovia . Ak súbor foo.txt už obsahuje nejaký obsah, potom systémové volania write a prepíšu obsah a všetok predchádzajúci obsah je vymazané a len ahojte geekovia obsah bude mať v súbore.

Príklad: Vytlačte ahoj svet z programu bez použitia funkcie printf.

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

Výkon

hello world 

V tomto kóde reťazec poľa buf1 ahoj svet sa najprv zapíše do štandardnej adresy fd[0] a potom sa tento reťazec zapíše do štandardnej adresy do poľa buf2. Potom zapíšte do poľa buf2 na stdout a vytlačte výstup ahoj svet .