Le chiamate di sistema sono le chiamate che un programma effettua al kernel del sistema per fornire i servizi a cui il programma non ha accesso diretto. Ad esempio, fornendo accesso a dispositivi di input e output come monitor e tastiere. Possiamo utilizzare varie funzioni fornite nel linguaggio di programmazione C per le chiamate di sistema di input/output come creare, aprire, leggere, scrivere, ecc.
Prima di passare alle chiamate di sistema I/O, è necessario conoscere alcuni termini importanti.
Terminologia importante
Cos'è il descrittore di file?
Il descrittore di file è un numero intero che identifica in modo univoco un file aperto del processo.
Tabella descrittore di file: un file la tabella descrittore è la raccolta di indici di array di numeri interi che sono descrittori di file in cui gli elementi sono puntatori alle voci della tabella di file. Nel sistema operativo viene fornita una tabella di descrittori di file univoca per ciascun processo.
Voce tabella file: Le voci della tabella file sono una struttura surrogata in memoria di un file aperto, creata durante l'elaborazione di una richiesta di apertura del file e queste voci mantengono la posizione del file.

Descrittori di file standard : All'avvio di un processo, il fd (descrittore di file) 0, 1, 2 della tabella dei descrittori di file di processo si apre automaticamente, (per impostazione predefinita) ciascuno di questi 3 fd fa riferimento alla voce della tabella di file per un file denominato /dev/tty
/dev/tty : surrogato in memoria del terminale.
conversione di int in stringa in Java
terminale : Combinazione tastiera/schermo video.

Leggi da stdin => leggi da fd 0 : Ogni volta che scriviamo un carattere dalla tastiera, questo legge da stdin a fd 0 e lo salva in un file chiamato /dev/tty.
Scrivi su stdout => scrivi su fd 1 : Ogni volta che vediamo un output sullo schermo video, proviene dal file denominato /dev/tty e scritto su stdout sullo schermo tramite fd 1.
Scrivi su stderr => scrivi su fd 2 : Vengono visualizzati eventuali errori sullo schermo video, è anche da quel file scritto su stderr sullo schermo tramite fd 2.
Chiamate di sistema di ingresso/uscita
Fondamentalmente, ci sono 5 tipi totali di chiamate di sistema I/O:
1. C crea
La funzione create() viene utilizzata per creare un nuovo file vuoto in C. Possiamo specificare il permesso e il nome del file che vogliamo creare utilizzando la funzione create(). È definito all'interno al suo interno sono definiti il file header e i flag che vengono passati come argomenti file di intestazione.
Sintassi di create() in C
int create (char * filename , mode_t mode );>
Parametro
- nome del file: nome del file che vuoi creare
- modalità: indica i permessi del nuovo file.
Valore di ritorno
- restituisce il primo descrittore di file inutilizzato (generalmente 3 quando viene creato per la prima volta nel processo perché 0, 1, 2 fd sono riservati)
- restituisce -1 in caso di errore
Come funziona C create() nel sistema operativo
- Crea un nuovo file vuoto sul disco.
- Crea una voce nella tabella dei file.
- Imposta il primo descrittore di file inutilizzato in modo che punti alla voce della tabella file.
- Restituisce il descrittore di file utilizzato, -1 in caso di errore.
2. C aperto
La funzione open() in C viene utilizzata per aprire il file per la lettura, la scrittura o entrambi. È anche in grado di creare il file se non esiste. È definito all'interno al suo interno sono definiti il file header e i flag che vengono passati come argomenti file di intestazione.
Sintassi di open() in C
int open (const char* Path , int flags );>
Parametri
- Sentiero: Percorso del file che vogliamo aprire.
- Usa il percorso assoluto a cominciare da / quando sei non lavorando nella stessa directory come file sorgente C.
- Utilizzo percorso relativo che è solo il nome del file con estensione, quando lo sei lavorando nella stessa directory come file sorgente C.
- bandiere: Viene utilizzato per specificare come si desidera aprire il file. Possiamo usare i seguenti flag.
| Bandiere | Descrizione |
|---|---|
| O_RDONLY | Apre il file in modalità di sola lettura. |
| O_SBAGLIATO | Apre il file in modalità di sola scrittura. |
| O_RDWR | Apre il file in modalità lettura e scrittura. |
| O_CREATE | Crea un file se non esiste. |
| O_ESCL | Impedisci la creazione se esiste già. |
| O_ APPEND | Apre il file e posiziona il cursore alla fine del contenuto. |
| O_ASINC | Abilita il controllo degli ingressi e delle uscite tramite segnale. |
| O_CLOEXEC | Abilita la modalità close-on-exec sul file aperto. |
| O_NONBLOCCO | Disabilita il blocco del file aperto. |
| O_TMPFILE | Crea un file temporaneo senza nome nel percorso specificato. |
Come funziona C open() nel sistema operativo
- Trova il file esistente sul disco.
- Crea una voce nella tabella dei file.
- Imposta il primo descrittore di file inutilizzato in modo che punti alla voce della tabella file.
- Restituisce il descrittore di file utilizzato, -1 in caso di errore.
Esempio di 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;> }> |
>
>
Produzione
fd = 3>
3. C chiudi
La funzione close() in C dice al sistema operativo che hai finito con un descrittore di file e chiude il file indicato dal descrittore di file. È definito all'interno file di intestazione.
Sintassi di close() in C
int close(int fd);>
Parametro
- fd: F descrittore ile del file che desideri chiudere.
Valore di ritorno
- 0 sul successo.
- -1 sull'errore.
Come funziona C close() nel sistema operativo
- Distrugge la voce della tabella dei file a cui fa riferimento l'elemento fd della tabella dei descrittori di file
– Finché nessun altro processo lo indica! - Imposta l'elemento fd della tabella dei descrittori di file su NULLO
Esempio 1: close() in 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.
'>);> }> |
>
>
Produzione
opened the fd = 3 closed the fd.>
Esempio 2:
C
algoritmo della cabina
// 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);> }> |
>
>
Produzione
fd2 = 3>
Qui, in questo codice prima ritorna open() 3 perché quando viene creato il processo principale, fd 0, 1, 2 sono già presi da stdin , stdout, E stderr . Quindi il primo descrittore di file inutilizzato è 3 nella tabella dei descrittori di file. Dopodiché in close() la chiamata di sistema è gratuita 3 descrittori di file e quindi impostare 3 descrittori di file come nullo . Quindi, quando abbiamo chiamato la seconda open(), lo è anche la prima fd inutilizzata 3 . Quindi, l'output di questo programma è 3 .
4. C leggi
Dal file indicato dal descrittore di file fd, la funzione read() legge la quantità di byte specificata cnt di input nell'area di memoria indicata da buf . Una lettura riuscita () aggiorna il tempo di accesso per il file. Anche la funzione read() è definita all'interno del file header.
Sintassi di read() in C
size_t read (int fd , void* buf , size_t cnt );>
Parametri
- fd: descrittore di file del file da cui devono essere letti i dati.
- bu: buffer da cui leggere i dati
- cnt: lunghezza del buffer
Valore di ritorno
- return Numero di byte letti in caso di successo
- restituisce 0 al raggiungimento della fine del file
- restituisce -1 in caso di errore
- restituisce -1 all'interruzione del segnale
Punti importanti
- buf deve puntare a una posizione di memoria valida con una lunghezza non inferiore alla dimensione specificata a causa dell'overflow.
- fd dovrebbe essere un descrittore di file valido restituito da open() per eseguire l'operazione di lettura perché se fd è NULL la lettura dovrebbe generare un errore.
- cnt è il numero richiesto di byte letti, mentre il valore restituito è il numero effettivo di byte letti. Inoltre, a volte la chiamata di sistema read dovrebbe leggere meno byte di cnt.
Esempio di read() in 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;> }> |
>
>
Produzione
called read(3, c, 10). returned that 10 bytes were read. Those bytes are as follows: 0 0 0 foo.>
Supponiamo che foobar.txt sia costituito dai 6 caratteri ASCII foobar. Allora qual è l'output del seguente programma?
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);> }> |
>
come si deseleziona in gimp
>
Produzione
c = f>
I descrittori fd1 E fd2 ognuno ha la propria voce nella tabella dei file aperti, quindi ogni descrittore ha la propria posizione nel file foobar.txt . Pertanto, la lettura da fd2 legge il primo byte di foobar.txt e l'output è c = f , non c = o .
5. C scrivere
Scrive cnt byte da buf nel file o nel socket associato a fd. cnt non deve essere maggiore di INT_MAX (definito nel file di intestazione limit.h). Se cnt è zero, write() restituisce semplicemente 0 senza tentare altre azioni.
Anche il write() è definito all'interno file di intestazione.
Sintassi di write() in C
size_t write (int fd , void* buf , size_t cnt );>
Parametri
- fd: descrittore di file
- buf: buffer da cui scrivere i dati.
- cnt: lunghezza del buffer.
Valore di ritorno
- restituisce il numero di byte scritti in caso di successo.
- restituire 0 al raggiungimento della fine del file.
- restituisce -1 in caso di errore.
- restituisce -1 sulle interruzioni del segnale.
Punti importanti sulla scrittura in C
- Il file deve essere aperto per le operazioni di scrittura
- buf deve essere lungo almeno quanto specificato da cnt perché se la dimensione buf è inferiore a cnt allora buf porterà alla condizione di overflow.
- cnt è il numero richiesto di byte da scrivere, mentre il valore restituito è il numero effettivo di byte scritti. Questo accade quando fd ha un numero inferiore di byte da scrivere rispetto a cnt.
- Se write() viene interrotto da un segnale, l'effetto è uno dei seguenti:
- Se write() non ha ancora scritto alcun dato, restituisce -1 e imposta errno su EINTR.
- Se write() ha scritto con successo alcuni dati, restituisce il numero di byte che ha scritto prima di essere interrotto.
Esempio di write() in 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);> }> |
>
>
motore di ricerca ed esempi
Produzione
called write(3, 'hello geeks ', 12). it returned 11>
Qui, quando vedi il file foo.txt dopo aver eseguito il codice, ottieni a ciao geek . Se il file foo.txt contiene già del contenuto, le chiamate di sistema write a sovrascrivono il contenuto e tutto il contenuto precedente lo sarà cancellato e solo ciao geek il contenuto avrà nel file.
Esempio: stampa hello world dal programma senza utilizzare alcuna funzione 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;> }> |
>
>
Produzione
hello world>
In questo codice, la stringa dell'array buf1 Ciao mondo viene prima scritta in stdin fd[0], quindi questa stringa viene scritta in stdin nell'array buf2. Successivamente scrivi nell'array buf2 sullo stdout e stampa l'output Ciao mondo .