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.

Š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.
powershell viacriadkový komentár

Čí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
dĺžka java reťazca
// 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);> }> |
relácia vypršala
>
>
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 .