modifiche varie + aggiunte sull'environment
[gapil.git] / fileunix.tex
index a0d1defd7eda6045b51c76c2d0b3e60da9089eb6..8c33fa3b90613f16c9c6f499451c957cb6b2ddc7 100644 (file)
@@ -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}
@@ -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).
@@ -793,12 +793,12 @@ 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 è
-semplicamente quello di copiare il valore nella struttura \var{file\_struct},
-cosicché anche il nuovo file descriptor fa riferirimento alla stessa voce
+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}
@@ -839,7 +839,7 @@ 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
-effettare una \func{close}, perdendo l'atomicità dell'operazione.
+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};
@@ -860,7 +860,7 @@ file descriptor viene usata la funzione \func{fcntl} il cui prototipo 
   \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)}
+  \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}.
   
@@ -874,7 +874,8 @@ file descriptor viene usata la funzione \func{fcntl} il cui prototipo 
 
 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, una lista dei possibili valori è riportata di seguito:
+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
@@ -883,7 +884,7 @@ un esempio, una lista dei possibili valori 
   \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 è
+  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
@@ -892,16 +893,88 @@ un esempio, una lista dei possibili valori 
 \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}).
+  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.