X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=blobdiff_plain;f=fileunix.tex;h=8c33fa3b90613f16c9c6f499451c957cb6b2ddc7;hp=3001194b17762a7e3b4c5d321e6e9e98d873fe28;hb=b7520f656813ad8056bdf95eb4d7b41c0292058e;hpb=132101028053d47151d1957b925fc5a7631c01e6 diff --git a/fileunix.tex b/fileunix.tex index 3001194..8c33fa3 100644 --- a/fileunix.tex +++ b/fileunix.tex @@ -34,7 +34,7 @@ ogni ulteriore operazione. All'interno di ogni processo i file aperti sono identificati da un intero non negativo, chiamato appunto \textit{file descriptor}, quando un file viene aperto la funzione restituisce il file descriptor, e tutte le successive -operazioni devono passare il \textit{file descriptors} come argomento. +operazioni devono passare il \textit{file descriptor} come argomento. Per capire come funziona il meccanismo occorre spiegare a grandi linee come è che il kernel gestisce l'interazione fra processi e file. Il kernel mantiene @@ -78,7 +78,7 @@ questa architettura, in cui si sono evidenziate le interrelazioni fra le varie strutture di dati sulla quale essa è basata. \begin{figure}[htb] \centering - \includegraphics[width=14cm]{img/procfile.eps} + \includegraphics[width=14cm]{img/procfile} \caption{Schema della architettura dell'accesso ai file attraverso l'interfaccia dei \textit{file descriptor}} \label{fig:file_proc_file} @@ -194,7 +194,7 @@ prototipo che non esiste. \item \macro{ETXTBSY} si è cercato di accedere in scrittura all'immagine di un programma in esecuzione. - \item \macro{ELOOP} si sono incotrati troppi link simbolici nel risolvere + \item \macro{ELOOP} si sono incontrati troppi link simbolici nel risolvere pathname o si è indicato \macro{O\_NOFOLLOW} e \var{pathname} è un link simbolico. \end{errlist} @@ -205,8 +205,8 @@ prototipo La funzione apre il file, usando il primo file descriptor libero, e crea l'opportuna voce (cioè la struttura \var{file}) nella file table. Viene usato -sempre il file descriptor con il valore più basso, questa caratteristica -permette di prevedere qual'è il valore che si otterrà e viene talvolta usata +sempre il file descriptor con il valore più basso. Questa caratteristica +permette di prevedere qual'è il valore che si otterrà, e viene talvolta usata da alcune applicazioni per sostituire i file corrispondenti ai file standard di \secref{sec:file_std_descr}: se ad esempio si chiude lo standard input e si apre subito dopo un nuovo file questo diventerà il nuovo standard input (avrà @@ -219,11 +219,11 @@ cio \hline \textbf{Flag} & \textbf{Descrizione} \\ \hline - \hline % modailtà di accesso al file + \hline % modalità di accesso al file \macro{O\_RDONLY} & apre il file in sola lettura. \\ \macro{O\_WRONLY} & apre il file in sola scrittura. \\ \macro{O\_RDWR} & apre il file lettura/scrittura. \\ - \hline % modalita di apertura del file + \hline % modalità di apertura del file \hline \macro{O\_CREAT} & se il file non esiste verrà creato, con le regole di titolarità del file viste in \secref{sec:file_ownership}. Il parametro @@ -273,7 +273,8 @@ cio \macro{O\_NDELAY} & in Linux\footnotemark\ è sinonimo di \macro{O\_NONBLOCK}.\\ \macro{O\_ASYNC} & apre il file per l'input/output in modalità - asincrona. Non è supportato in Linux. \\ + asincrona. Quando è settato viene generato un segnale di \macro{SIGIO} + tutte le volte che è disponibile dell'input sul file. \\ \macro{O\_SYNC} & apre il file per l'input/output sincrono, ogni \func{write} bloccherà fino al completamento della scrittura di tutti dati sul sull'hardware sottostante.\\ @@ -284,8 +285,7 @@ cio di montaggio.\\ \hline \end{tabular} - \caption{Costanti definite in \file{fcntl.h} per indicare i vari bit - usabili per il specificare parametro \var{flags} di \func{open}.} + \caption{Valori e significato dei vari bit del \textit{file status flag}.} \label{tab:file_open_flags} \end{table} @@ -415,7 +415,7 @@ sua volta pu Come già accennato in \secref{sec:file_fd} a ciascun file aperto è associata una \textsl{posizione corrente nel file} (il cosiddetto \textit{file offset}, mantenuto nel campo \var{f\_pos} di \var{file}) espressa da un numero intero -positivo come numero di bytes dall'inizio del file. Tutte le operazioni di +positivo come numero di byte dall'inizio del file. Tutte le operazioni di lettura e scrittura avvengono a partire da questa posizione che viene automaticamente spostata in avanti del numero di byte letti o scritti. @@ -442,14 +442,14 @@ sommato al riferimento dato da \var{whence}; quest'ultimo pu seguenti valori\footnote{per compatibilità con alcune vecchie notazioni questi valori possono essere rimpiazzati rispettivamente con 0, 1 e 2 o con \macro{L\_SET}, \macro{L\_INCR} e \macro{L\_XTND}}: -\begin{description} -\item \macro{SEEK\_SET} si fa riferimento all'inizio del file: il valore di +\begin{basedescript}{\desclabelwidth{2.0cm}} +\item[\macro{SEEK\_SET}] si fa riferimento all'inizio del file: il valore di \var{offset} è la nuova posizione. -\item \macro{SEEK\_CUR} si fa riferimento alla posizione corrente del file: +\item[\macro{SEEK\_CUR}] si fa riferimento alla posizione corrente del file: \var{offset} che può essere negativo e positivo. -\item \macro{SEEK\_END} si fa riferimento alla fine del file: il valore di +\item[\macro{SEEK\_END}] si fa riferimento alla fine del file: il valore di \var{offset} può essere negativo e positivo. -\end{description} +\end{basedescript} Come accennato in \secref{sec:file_file_size} con \func{lseek} è possibile settare la posizione corrente anche al di la della fine del file, e alla @@ -485,14 +485,14 @@ Per leggere da un file precedentemente aperto, si pu il cui prototipo è: \begin{prototype}{unistd.h}{ssize\_t read(int fd, void * buf, size\_t count)} - La funzione cerca di leggere \var{count} bytes dal file \var{fd} al buffer + La funzione cerca di leggere \var{count} byte dal file \var{fd} al buffer \var{buf}. La funzione ritorna il numero di byte letti in caso di successo e -1 in caso di errore, nel qual caso \var{errno} viene settata ad uno dei valori: \begin{errlist} \item \macro{EINTR} la funzione è stata interrotta da un segnale prima di - aver potuto leggere quasiasi dato. + aver potuto leggere qualsiasi dato. \item \macro{EAGAIN} la funzione non aveva nessun dato da restituire e si era aperto il file in modalità \macro{O\_NONBLOCK}. \end{errlist} @@ -503,7 +503,7 @@ il cui prototipo La funzione tenta di leggere \var{count} byte a partire dalla posizione corrente nel file; dopo la lettura la posizione è spostata automaticamente in -avanti del numero di bytes letti. Se \var{count} è zero la funzione +avanti del numero di byte letti. Se \var{count} è zero la funzione restituisce zero senza nessun altro risultato. Si deve sempre tener presente che non è detto che la funzione \func{read} @@ -512,7 +512,7 @@ la funzione pu comportamento normale e non un errore, che però bisogna sempre tenere presente. -La prima e più ovvia di queste ragioni è che si è chiesto di leggere più bytes +La prima e più ovvia di queste ragioni è che si è chiesto di leggere più byte di quanto il file ne contenga. In questo caso il file viene letto fino alla sua fine, e la funzione ritorna regolarmente il numero di byte letti effettivamente. Se ripetessimo la lettura \func{read} restituirebbe uno zero. @@ -548,7 +548,7 @@ sono dati in ingresso: la funzione allora ritorna immediatamente con un errore Lo standard Unix98\footnote{questa funzione, e l'analoga \func{pwrite} sono state aggiunte nel kernel 2.1.60, il supporto nelle \acr{glibc}, compresa l'emulazione per i vecchi kernel che non hanno la system call, è stato - aggiutno con la versione 2.1} (vedi \secref{sec:intro_opengroup}) prevede la + aggiunto con la versione 2.1} (vedi \secref{sec:intro_opengroup}) prevede la definizione di un'altra funzione di lettura, \func{pread}, che diventa accessibile con la definizione: \begin{verbatim} @@ -558,7 +558,7 @@ il prototipo di questa funzione \begin{prototype}{unistd.h} {ssize\_t pread(int fd, void * buf, size\_t count, off\_t offset)} -La funzione cerca di leggere \var{count} bytes dal file \var{fd}, a partire +La funzione cerca di leggere \var{count} byte dal file \var{fd}, a partire dalla posizione \var{offset}, nel buffer \var{buf}. La funzione ritorna il numero di byte letti in caso di successo e -1 in caso @@ -580,7 +580,7 @@ all'inizio del file. Per scrivere su un file si usa la funzione \func{write}, il cui prototipo è: \begin{prototype}{unistd.h}{ssize\_t write(int fd, void * buf, size\_t count)} - La funzione scrive \var{count} bytes dal buffer \var{buf} sul file \var{fd}. + La funzione scrive \var{count} byte dal buffer \var{buf} sul file \var{fd}. La funzione ritorna il numero di byte scritti in caso di successo e -1 in caso di errore, nel qual caso \var{errno} viene settata ad uno dei valori: @@ -595,7 +595,7 @@ Per scrivere su un file si usa la funzione \func{write}, il cui prototipo \macro{SIGPIPE}, se questo viene gestito (o bloccato o ignorato) la funzione ritorna questo errore. \item \macro{EINTR} la funzione è stata interrotta da un segnale prima di - aver potuto scerivere quasiasi dato. + aver potuto scrivere qualsiasi dato. \item \macro{EAGAIN} la funzione non aveva nessun dato da restituire e si era aperto il file in modalità \macro{O\_NONBLOCK}. \end{errlist} @@ -606,7 +606,7 @@ Per scrivere su un file si usa la funzione \func{write}, il cui prototipo Come nel caso di \func{read} la funzione tenta di scrivere \var{count} byte a partire dalla posizione corrente nel file e sposta automaticamente la -posizione in avanti del numero di bytes scritti. Se il file è aperto in +posizione in avanti del numero di byte scritti. Se il file è aperto in modalità \macro{O\_APPEND} i dati vengono sempre scritti alla fine del file. Lo standard POSIX richiede che i dati scritti siano immediatamente disponibili ad una \func{read} chiamata dopo che la \func{write} che li ha scritti è @@ -614,7 +614,7 @@ ritornata; ma dati i meccanismi di caching non supportino questa capacità. Se \var{count} è zero la funzione restituisce zero senza fare nient'altro. Per -i file ordinari il numero di bytes scritti è sempre uguale a quello indicato +i file ordinari il numero di byte scritti è sempre uguale a quello indicato da \var{count}, a meno di un errore. Negli altri casi si ha lo stesso comportamento di \func{read}. @@ -625,7 +625,7 @@ suo prototipo {ssize\_t pwrite(int fd, void * buf, size\_t count, off\_t offset)} La funzione cerca di scrivere sul file \var{fd}, a partire dalla posizione -\var{offset}, \var{count} bytes dal buffer \var{buf}. +\var{offset}, \var{count} byte dal buffer \var{buf}. La funzione ritorna il numero di byte letti in caso di successo e -1 in caso di errore, nel qual caso \var{errno} viene settata secondo i valori già visti @@ -637,7 +637,7 @@ per \func{write} e \func{lseek}. \section{Caratteristiche avanzate} \label{sec:file_adv_func} -In questa sezione approfondireme alcune delle caratteristiche più sottili +In questa sezione approfondiremo alcune delle caratteristiche più sottili della gestione file in un sistema unix-like, esaminando in dettaglio il comportamento delle funzioni base, inoltre tratteremo alcune funzioni che permettono di eseguire operazioni avanzate con i file. @@ -654,7 +654,7 @@ confronti dell'accesso allo stesso file da parte di processi diversi. \begin{figure}[htb] \centering - \includegraphics[width=14cm]{img/filemultacc.eps} + \includegraphics[width=14cm]{img/filemultacc} \caption{Schema dell'accesso allo stesso file da parte di due processi diversi} \label{fig:file_mult_acc} @@ -689,14 +689,14 @@ stesso file, in particolare occorre tenere presente che: \begin{figure}[htb] \centering - \includegraphics[width=14cm]{img/fileshar.eps} + \includegraphics[width=14cm]{img/fileshar} \caption{Schema dell'accesso ai file da parte di un processo figlio} \label{fig:file_acc_child} \end{figure} È comunque possibile che due file descriptor di due processi diversi puntino alla stessa voce nella \textit{file table}; questo è ad esempio il caso dei -file aperti che venfono ereditati dal processo figlio all'esecuzione di una +file aperti che vengono ereditati dal processo figlio all'esecuzione di una \func{fork} (si ricordi quanto detto in \secref{sec:proc_fork}). La situazione è illustrata in \figref{fig:file_acc_child}; dato che il processo figlio riceve una copia dello spazio di indirizzi del padre, riceverà anche una copia @@ -704,7 +704,7 @@ di \var{file\_struct} e relativa tabella dei file aperti. In questo modo padre e figlio avranno gli stessi file descriptor che faranno riferimento alla stessa voce nella \textit{file table}, condividendo così la -posizione corrente sul file. Questo ha le cosenguenze descritte a suo tempo in +posizione corrente sul file. Questo ha le conseguenze descritte a suo tempo in \secref{sec:proc_fork}: in caso di scrittura contemporanea la posizione corrente nel file varierà per entrambi i processi (in quanto verrà modificato \var{f\_pos} che è la stesso per entrambi). @@ -758,29 +758,223 @@ creare un file di lock, bloccandosi se il file esiste. In questo caso la sequenza logica porterebbe a verificare prima l'esistenza del file con una \func{stat} per poi crearlo con una \func{creat}; di nuovo avremmo la possibilità di una race condition da parte di un altro processo che crea lo -stesso file fra il controllo e la creazione. - -Per questo motivo sono stati introdotti i flag \macro{O\_CREAT} -\macro{O\_EXCL} +stesso file fra il controllo e la creazione. +Per questo motivo sono stati introdotti i due flag \macro{O\_CREAT} e +\macro{O\_EXCL}, in questo modo l'operazione di controllo dell'esistenza del +file (con relativa uscita dalla funzione con un errore) e creazione in caso di +assenza, diventa atomica essendo svolta tutta all'interno di una singola +\func{open}. \subsection{La funzioni \func{dup} e \func{dup2}} \label{sec:file_dup} +Abbiamo già visto in \secref{sec:file_sharing} come un processo figlio +condivida gli stessi file descriptor del padre; è possibile però ottenere un +comportamento analogo all'interno di uno stesso processo \textit{duplicando} +un file descriptor. Per far questo si usa la funzione \func{dup} il cui +prototipo è: +\begin{prototype}{unistd.h}{int dup(int oldfd)} + + La funzione crea una copia del file descriptor \param{oldfd}. + + La funzione ritorna il nuovo file descriptor in caso di successo e -1 in + caso di errore, nel qual caso \var{errno} viene settata ad uno dei valori: + \begin{errlist} + \item \macro{EBADF} \param{oldfd} non è un file aperto. + \item \macro{EMFILE} si è raggiunto il numero massimo consentito di file + descriptor aperti. + \end{errlist} +\end{prototype} +La funzione ritorna, come \func{open}, il primo file descriptor libero. Il +file descriptor è una copia esatta del precedente ed entrambi possono essere +interscambiati nell'uso. Per capire meglio il funzionamento della funzione si +può fare riferimento a \figref{fig:file_dup}: l'effetto della funzione è +semplicemente quello di copiare il valore nella struttura \var{file\_struct}, +cosicché anche il nuovo file descriptor fa riferimento alla stessa voce +nella \textit{file table}. \begin{figure}[htb] - \centering \includegraphics[width=14cm]{img/filedup.eps} + \centering \includegraphics[width=14cm]{img/filedup} \caption{Schema dell'accesso ai file duplicati} \label{fig:file_dup} \end{figure} +In questo modo entrambi i file condivideranno eventuali lock, \textit{file + status flag}, e posizione corrente: se ad esempio \func{lseek} modifica la +posizione su uno dei due file descriptor essa sarà modificata anche sull'altro +(al solito viene modificato lo stesso campo nella voce della \textit{file + table} a cui entrambi fanno riferimento). + +L'unica differenza fra i due file descriptor è che ciascuno avrà il suo +\textit{file descriptor flag}; nel caso di \func{dup} il flag di \textit{close + on exec} viene sempre cancellato nella copia. + +Una diversa versione della funzione, \func{dup2} viene utilizzata per +specificare esplicitamente il nuovo file descriptor; il suo prototipo è: +\begin{prototype}{unistd.h}{int dup2(int oldfd, int newfd)} + + La funzione rende \param{newfd} una copia del file descriptor \param{oldfd}. + + La funzione ritorna il nuovo file descriptor in caso di successo e -1 in + caso di errore, nel qual caso \var{errno} viene settata ad uno dei valori: + \begin{errlist} + \item \macro{EBADF} \param{oldfd} non è un file aperto o \param{newfd} ha un + valore fuori dall'intervallo consentito per i file descriptor. + \item \macro{EMFILE} si è raggiunto il numero massimo consentito di file + descriptor aperti. + \end{errlist} +\end{prototype} +\noindent la funzione chiude il file descriptor \param{newfd} se è aperto. + +La duplicazione dei file descriptor può essere effettuata anche usando la +funzione di controllo dei file \func{fnctl} (che esamineremo in +\secref{sec:file_fcntl}) con il parametro \macro{F\_DUPFD}. + +L'operazione ha la sintassi \func{fnctl(oldfd, F\_DUPFD, newfd)} e se si usa 0 +come valore per \param{newfd} diventa equivalente a \func{dup}. La sola +differenza, a parte i codici di errore, è che \func{dup2} chiude il nuovo file +se è già aperto mentre \func{fcntl} apre il primo disponibile con un valore +superiore, per cui per poterla usare come \func{dup2} occorrerebbe prima +effettuare una \func{close}, perdendo l'atomicità dell'operazione. + +L'uso principale di queste funzioni è per la redirezione dell'input e +dell'output fra l'esecuzione di una \func{fork} e la successiva \func{exec}; +diventa così possibile associare un file (o una pipe) allo standard input o +allo standard output, torneremo su questo uso più avanti quando tratteremo le +pipe. + \subsection{La funzione \func{fcntl}} \label{sec:file_fcntl} +Oltre alle operazioni base esaminate in \secref{sec:file_base_func} esistono +tutta una serie di operazioni ausiliarie che è possibile eseguire su un file +descriptor. Per queste operazioni di manipolazione delle varie proprietà di un +file descriptor viene usata la funzione \func{fcntl} il cui prototipo è: +\begin{functions} + \headdecl{unistd.h} + \headdecl{fcntl.h} + \funcdecl{int fcntl(int fd, int cmd)} + \funcdecl{int fcntl(int fd, int cmd, long arg)} + \funcdecl{int fcntl(int fd, int cmd, struct flock * lock)} + La funzione esegue una delle possibili operazioni specificate da \param{cmd} + sul file \param{fd}. + + La funzione ha valori di ritorno diversi a seconda dell'operazione. In caso + di errore il valore di ritorno è -1 e la variabile \var{errno} viene settata + ad un opportuno codice, quelli validi in generale sono: + \begin{errlist} + \item \macro{EBADF} \param{oldfd} non è un file aperto. + \end{errlist} +\end{functions} + +Il comportamento di questa funzione è determinato dal valore del comando +\param{cmd} che le viene fornito; in \secref{sec:file_dup} abbiamo incontrato +un esempio per la duplicazione dei file descriptor, una lista dei possibili +valori è riportata di seguito: +\begin{basedescript}{\desclabelwidth{2.0cm}} +\item[\macro{F\_DUPFD}] trova il primo file descriptor disponibile di valore + maggiore o uguale ad \param{arg} e ne fa una copia di \var{fd}. In caso di + successo ritorna il nuovo file descriptor. Gli errori possibili sono + \macro{EINVAL} se \param{arg} è negativo o maggiore del massimo consentito o + \macro{EMFILE} se il processo ha già raggiunto il massimo numero di + descrittori consentito. +\item[\macro{F\_SETFD}] setta il valore del \textit{file descriptor flag} + al valore specificato con \param{arg}. Al momento l'unico bit usato è + quello di \textit{close on exec}, identificato dalla costante + \macro{FD\_CLOEXEC}. +\item[\macro{F\_GETFD}] ritorna il valore del \textit{file descriptor flag} di + \var{fd}, se \macro{FD\_CLOEXEC} è settato i file descriptor aperti vengono + chiusi attraverso una \func{exec} altrimenti (il default) restano aperti. +\item[\macro{F\_GETFL}] ritorna il valore del \textit{file status flag}, + permette cioè di rileggere quei bit settati da \func{open} all'apertura del + file che vengono memorizzati (quelli riportati nella prima e terza sezione + di \tabref{tab:file_open_flags}). +\item[\macro{F\_SETFL}] setta il \textit{file status flag} al valore + specificato da \param{arg}, possono essere settati solo i bit riportati + nella terza sezione di \tabref{tab:file_open_flags} (da verificare). +\item[\macro{F\_GETLK}] se un file lock è attivo restituisce nella struttura + \param{lock} la struttura \type{flock} che impedisce l'acquisizione del + blocco, altrimenti setta il campo \var{l\_type} a \macro{F\_UNLCK} (per i + dettagli sul \textit{file locking} vedi \secref{sec:file_locking}). +\item[\macro{F\_SETLK}] richiede il file lock specificato da \param{lock} se + \var{l\_type} è \macro{F\_RDLCK} o \macro{F\_WRLLCK} o lo rilascia se + \var{l\_type} è \macro{F\_UNLCK}. Se il lock è tenuto da qualcun'altro + ritorna immediatamente restituendo -1 e setta \var{errno} a \macro{EACCES} o + \macro{EAGAIN} (per i dettagli sul \textit{file locking} vedi + \secref{sec:file_locking}). +\item[\macro{F\_SETLKW}] identica a \macro{F\_SETLK} eccetto per il fatto che + la funzione non ritorna subito ma attende che il blocco sia rilasciato. Se + l'attesa viene interrotta da un segnale la funzione restituisce -1 e setta + \var{errno} a \macro{EINTR} (per i dettagli sul \textit{file locking} vedi + \secref{sec:file_locking}). +\item[\macro{F\_GETOWN}] restituisce il \acr{pid} del processo o il process + group che è preposto alla ricezione dei segnali \macro{SIGIO} e + \macro{SIGURG} per gli eventi associati al file descriptor \var{fd}. Il + process group è restituito come valore negativo. +\item[\macro{F\_SETOWN}] setta il processo o process group che riceverà i + sengali \macro{SIGIO} e \macro{SIGURG} per gli eventi associati al file + descriptor \var{fd}. I process group sono settati usando valori negativi. +\item[\macro{F\_GETSIG}] restituisce il segnale mandato quando ci sono dati + disponibili in input sul file descriptor. Il valore 0 indica il default (che + è \macro{SIGIO}), un valore diverso da zero indica il segnale richiesto, + (che può essere lo stesso \macro{SIGIO}), nel qual caso al manipolatore del + segnale, se installato con \macro{SA\_SIGINFO}, vengono rese disponibili + informazioni ulteriori informazioni. +\item[\macro{F\_SETSIG}] setta il segnale da inviare quando diventa possibile + effettuare I/O sul file descriptor. Il valore zero indica il default + (\macro{SIGIO}), ogni altro valore permette di rendere disponibile al + manipolatore del segnale ulteriori informazioni se si è usata + \macro{SA\_SIGINFO}. +\end{basedescript} + +La maggior parte delle funzionalità di \func{fcntl} sono troppo avanzate per +poter essere affrontate in dettaglio a questo punto; saranno riprese più +avanti quando affronteremo le problematiche ad esse relative. + +Per determinare le modalità di accesso inoltre può essere necessario usare la + \subsection{La funzione \func{ioctl}} \label{sec:file_ioctl} +Benché il concetto di \textit{everything is a file} si sia dimostratato molto +valido anche per l'interazione con i più vari dispositivi, con cui si può +interagire con le stesse funzioni usate per i normali file di dati, +esisteranno sempre caratteristiche peculiari, specifiche dell'hardware e della +funzionalità che ciascuno di essi provvede, che non possono venire comprese in +questa interfaccia astratta (un caso tipico è il settaggio della velocità di +una porta seriale, o le dimensioni di un framebuffer). + +Per questo motivo l'architettura del sistema ha previsto l'esistenza di una +funzione speciale, \func{ioctl}, con cui poter compiere operazioni specifiche +per ogni singolo dispositivo. Il prototipo di questa funzione è: + +\begin{prototype}{sys/ioctl.h}{int ioctl(int fd, int request, ...)} + + La funzione manipola il sottostante dispositivo, usando il parametro + \param{request} per specificare l'operazione richiesta e il terzo parametro + (che usualmente è di tipo \param{char * argp}) per passare o ricevere + l'informazione necessaria al dispositivo. + + La funzione nella maggior parte dei casi ritorna 0, alcune operazioni usano + però il valore di ritorno per restituire informazoni. In caso di errore + viene sempre restituito -1 e \var{errno} viene settata ad uno dei valori + seguenti: + \begin{errlist} + \item \macro{ENOTTY} il file \param{fd} non è associato con un device. + \item \macro{EINVAL} gli argomenti \param{request} o \param{argp} non sono + validi. + \end{errlist} + ed inoltre \macro{EBADF} e \macro{EFAULT}. +\end{prototype} + +La funzione serve in sostanza per fare tutte quelle operazioni che non si +adattano all'architettura di I/O di unix e che non è possibile effettuare con +le funzioni esaminate finora. Per questo motivo non è possibile fare altro che +una descrizione generica; torneremo ad esaminarla in seguito, quando si +tratterà di applicarla ad alcune problematiche specifiche. +