X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=blobdiff_plain;f=fileunix.tex;h=54b1c190e97add774361d983c55ed8269a9de120;hp=f0243d46ea92eac1788c94bfb72c1915dbf875be;hb=e2a1ad24365266ea8846b688addd4e7694428969;hpb=d88ea986fbf6b84a802fd8a5665af4324a6c89b3 diff --git a/fileunix.tex b/fileunix.tex index f0243d4..54b1c19 100644 --- a/fileunix.tex +++ b/fileunix.tex @@ -201,11 +201,12 @@ prototipo \const{O\_CREAT} e \const{O\_EXCL}. \item[\errcode{EISDIR}] \var{pathname} indica una directory e si è tentato l'accesso in scrittura. - \item[\errcode{ENOTDIR}] si è specificato \const{O\_DIRECTORY} e \var{pathname} - non è una directory. - \item[\errcode{ENXIO}] si sono impostati \const{O\_NOBLOCK} o \const{O\_WRONLY} - ed il file è una fifo che non viene letta da nessun processo o - \var{pathname} è un file di dispositivo ma il dispositivo è assente. + \item[\errcode{ENOTDIR}] si è specificato \const{O\_DIRECTORY} e + \var{pathname} non è una directory. + \item[\errcode{ENXIO}] si sono impostati \const{O\_NOBLOCK} o + \const{O\_WRONLY} ed il file è una fifo che non viene letta da nessun + processo o \var{pathname} è un file di dispositivo ma il dispositivo è + assente. \item[\errcode{ENODEV}] \var{pathname} si riferisce a un file di dispositivo che non esiste. \item[\errcode{ETXTBSY}] si è cercato di accedere in scrittura all'immagine @@ -214,9 +215,9 @@ prototipo pathname o si è indicato \const{O\_NOFOLLOW} e \var{pathname} è un link simbolico. \end{errlist} - ed inoltre \const{EACCES}, \const{ENAMETOOLONG}, \const{ENOENT}, - \const{EROFS}, \const{EFAULT}, \const{ENOSPC}, \const{ENOMEM}, - \const{EMFILE} e \const{ENFILE}.} + ed inoltre \errval{EACCES}, \errval{ENAMETOOLONG}, \errval{ENOENT}, + \errval{EROFS}, \errval{EFAULT}, \errval{ENOSPC}, \errval{ENOMEM}, + \errval{EMFILE} e \errval{ENFILE}.} \end{functions} La funzione apre il file, usando il primo file descriptor libero, e crea @@ -404,7 +405,7 @@ descriptor ritorna disponibile; il suo prototipo \item[\errcode{EBADF}] \var{fd} non è un descrittore valido. \item[\errcode{EINTR}] la funzione è stata interrotta da un segnale. \end{errlist} - ed inoltre \const{EIO}.} + ed inoltre \errval{EIO}.} \end{prototype} La chiusura di un file rilascia ogni blocco (il \textit{file locking} è @@ -461,7 +462,7 @@ ad un valore qualsiasi con la funzione \func{lseek}, il cui prototipo \item[\errcode{ESPIPE}] \param{fd} è una pipe, un socket o una fifo. \item[\errcode{EINVAL}] \param{whence} non è un valore valido. \end{errlist} - ed inoltre \const{EBADF}.} + ed inoltre \errval{EBADF}.} \end{functions} La nuova posizione è impostata usando il valore specificato da \param{offset}, @@ -528,8 +529,8 @@ prototipo \item[\errcode{EAGAIN}] la funzione non aveva nessun dato da restituire e si era aperto il file in modalità \const{O\_NONBLOCK}. \end{errlist} - ed inoltre \const{EBADF}, \const{EIO}, \const{EISDIR}, \const{EBADF}, - \const{EINVAL} e \const{EFAULT} ed eventuali altri errori dipendenti dalla + ed inoltre \errval{EBADF}, \errval{EIO}, \errval{EISDIR}, \errval{EBADF}, + \errval{EINVAL} e \errval{EFAULT} ed eventuali altri errori dipendenti dalla natura dell'oggetto connesso a \var{fd}.} \end{prototype} @@ -641,8 +642,8 @@ scrivere su di esso utilizzando la funzione \func{write}, il cui prototipo \item[\errcode{EAGAIN}] la funzione non aveva nessun dato da restituire e si era aperto il file in modalità \const{O\_NONBLOCK}. \end{errlist} - ed inoltre \const{EBADF}, \const{EIO}, \const{EISDIR}, \const{EBADF}, - \const{ENOSPC}, \const{EINVAL} e \const{EFAULT} ed eventuali altri errori + ed inoltre \errval{EBADF}, \errval{EIO}, \errval{EISDIR}, \errval{EBADF}, + \errval{ENOSPC}, \errval{EINVAL} e \errval{EFAULT} ed eventuali altri errori dipendenti dalla natura dell'oggetto connesso a \var{fd}.} \end{prototype} @@ -697,7 +698,7 @@ confronti dell'accesso allo stesso file da parte di processi diversi. \begin{figure}[htb] \centering - \includegraphics[width=13cm]{img/filemultacc} + \includegraphics[width=15cm]{img/filemultacc} \caption{Schema dell'accesso allo stesso file da parte di due processi diversi} \label{fig:file_mult_acc} @@ -732,7 +733,7 @@ stesso file, in particolare occorre tenere presente che: \begin{figure}[htb] \centering - \includegraphics[width=13cm]{img/fileshar} + \includegraphics[width=15cm]{img/fileshar} \caption{Schema dell'accesso ai file da parte di un processo figlio} \label{fig:file_acc_child} \end{figure} @@ -868,7 +869,7 @@ usare le due funzioni \func{fsync} e \func{fdatasync}, i cui prototipi sono: \item[\errcode{EINVAL}] \param{fd} è un file speciale che non supporta la sincronizzazione. \end{errlist} - ed inoltre \const{EBADF}, \const{EROFS} e \const{EIO}.} + ed inoltre \errval{EBADF}, \errval{EROFS} e \errval{EIO}.} \end{functions} Entrambe le funzioni forzano la sincronizzazione col disco di tutti i dati del @@ -917,7 +918,7 @@ nella \textit{file table}; per questo si dice che il nuovo file descriptor \textsl{duplicato}, da cui il nome della funzione. \begin{figure}[htb] - \centering \includegraphics[width=13cm]{img/filedup} + \centering \includegraphics[width=15cm]{img/filedup} \caption{Schema dell'accesso ai file duplicati} \label{fig:file_dup} \end{figure} @@ -962,18 +963,21 @@ prototipo \end{prototype} \noindent e qualora il file descriptor \param{newfd} sia già aperto (come avviene ad esempio nel caso della duplicazione di uno dei file standard) esso -sarà prima chiuso e poi duplicato. +sarà prima chiuso e poi duplicato (così che il file duplicato sarà connesso +allo stesso valore per il file descriptor). 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 \const{F\_DUPFD}. +\secref{sec:file_fcntl}) con il parametro \const{F\_DUPFD}. L'operazione ha +la sintassi \code{fnctl(oldfd, F\_DUPFD, newfd)} e se si usa 0 come valore per +\param{newfd} diventa equivalente a \func{dup}. -L'operazione ha la sintassi \code{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. +La sola differenza fra le due funzioni\footnote{a parte la sistassi ed i + diversi codici di errore.} è che \func{dup2} chiude il file descriptor +\param{newfd} se questo è già aperto, garantendo che la duplicazione sia +effettuata esattamente su di esso, invece \func{fcntl} restituisce il primo +file descriptor libero di valore uguale o maggiore di \param{newfd} (e se +\param{newfd} è aperto la duplicazione avverrà su un altro file descriptor). \subsection{La funzione \func{fcntl}} @@ -981,8 +985,16 @@ effettuare una \func{close}, perdendo l'atomicit 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 è: +descriptor, che non riguardano la normale lettura e scrittura di dati, ma la +gestione sia delle loro proprietà, che di tutta una serie di ulteriori +funzionalità che il kernel può mettere a disposizione.\footnote{ad esempio si + gesticono con questa funzione l'I/O asincrono (vedi + \secref{sec:file_asyncronous_io}) e il file locking (vedi + \secref{sec:file_locking}).} + +Per queste operazioni di manipolazione e di controllo su proprietà e +caratteristiche un file descriptor, viene usata la funzione \func{fcntl}, il +cui prototipo è: \begin{functions} \headdecl{unistd.h} \headdecl{fcntl.h} @@ -1044,18 +1056,27 @@ valori l'attesa viene interrotta da un segnale la funzione restituisce -1 e imposta \var{errno} a \errcode{EINTR} (questa funzionalità è trattata in dettaglio in \secref{sec:file_posix_lock}). -\item[\const{F\_GETOWN}] restituisce il \acr{pid} del processo o il process - group che è preposto alla ricezione dei segnali \const{SIGIO} e - \const{SIGURG} per gli eventi associati al file descriptor \var{fd}. Il - process group è restituito come valore negativo. -\item[\const{F\_SETOWN}] imposta il processo o process group che riceverà i +\item[\const{F\_GETOWN}] restituisce il \acr{pid} del processo o + l'identificatore del process group\footnote{i \texttt{process group} sono + (vedi \secref{sec:sess_proc_group}) sono raggruppamenti di processi usati + nel controllo di sessione; a ciascuno di essi è associato un + identificatore (un numero positivo analogo al \acr{pid}).} che è preposto + alla ricezione dei segnali \const{SIGIO} e \const{SIGURG} per gli eventi + associati al file descriptor \var{fd}. Nel caso di un process group viene + restituito un valore negativo il cui valore assoluto corrisponde + all'identificatore del process group. +\item[\const{F\_SETOWN}] imposta, con il valore dell'argomento \param{arg}, + l'identificatore del processo o del \textit{process group} che riceverà i segnali \const{SIGIO} e \const{SIGURG} per gli eventi associati al file - descriptor \var{fd}. I process group sono impostati usando valori negativi. -\item[\const{F\_GETSIG}] restituisce il valore del segnale mandato quando ci - sono dati disponibili in input su un file descriptor aperto o impostato in - I/O asincrono. Il valore 0 indica il valore predefinito (che è - \const{SIGIO}), un valore diverso da zero indica il segnale richiesto, (che - può essere lo stesso \const{SIGIO}). + descriptor \var{fd}. Come per \const{F\_GETOWN}, per impostare un process + group si deve usare per \param{arg} un valore negativo, il cui valore + assoluto corrisponde all'identificatore del process group. +\item[\const{F\_GETSIG}] restituisce il valore del segnale inviato quando ci + sono dati disponibili in ingresso su un file descriptor aperto ed impostato + per l'I/O asincrono (si veda \secref{sec:file_asyncronous_io}). Il valore 0 + indica il valore predefinito (che è \const{SIGIO}), un valore diverso da + zero indica il segnale richiesto, (che può essere anche lo stesso + \const{SIGIO}). \item[\const{F\_SETSIG}] imposta il segnale da inviare quando diventa possibile effettuare I/O sul file descriptor in caso di I/O asincrono. Il valore zero indica di usare il segnale predefinito, \const{SIGIO}. Un altro @@ -1073,17 +1094,21 @@ valori 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 (in particolare -riprenderemo le tematiche relative all'I/O asincrono in -\secref{sec:file_asyncronous_io} e quelle relative al \textit{file locking} in -\secref{sec:file_locking}). +le tematiche relative all'I/O asincrono sono trattate in maniera esaustiva in +\secref{sec:file_asyncronous_io} mentre quelle relative al \textit{file + locking} saranno esaminate in \secref{sec:file_locking}). -Per determinare le modalità di accesso inoltre è necessario estrarre i bit di -accesso (ottenuti con il comando \const{F\_GETFL}); infatti la definizione -corrente non assegna bit separati a \const{O\_RDONLY}, \const{O\_WRONLY} e -\const{O\_RDWR},\footnote{posti rispettivamente ai valori 0, 1 e 2.} per cui il -valore si ottiene eseguendo un AND binario del valore di ritorno di -\func{fcntl} con la maschera \const{O\_ACCMODE} anch'essa definita in -\file{fcntl.h}. +Si tenga presente infine che quando si usa la funzione per determinare le +modalità di accesso con cui è stato aperto il file (attraverso l'uso del +comando \const{F\_GETFL}) è necessario estrarre i bit corripondenti nel +\textit{file status flag} che si è ottenuto. Infatti la definizione corrente +di quest'ultimo non assegna bit separati alle tre diverse modalità +\const{O\_RDONLY}, \const{O\_WRONLY} e \const{O\_RDWR}.\footnote{in Linux + queste costanti sono poste rispettivamente ai valori 0, 1 e 2.} Per questo +motivo il valore della modalità di accesso corrente si ottiene eseguendo un +AND binario del valore di ritorno di \func{fcntl} con la maschera +\const{O\_ACCMODE} (anch'essa definita in \file{fcntl.h}), che estrae i bit di +accesso dal \textit{file status flag}. @@ -1091,19 +1116,21 @@ valore si ottiene eseguendo un AND binario del valore di ritorno di \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 è l'impostazione 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 è: +valido anche per l'interazione con i dispositivi più vari, fornendo una +interfaccia che permette di interagire con essi tramite le stesse funzioni +usate per i normali file di dati, esisteranno sempre caratteristiche +peculiari, specifiche dell'hardware e della funzionalità che ciascun +dispositivo può provvedere, che non possono venire comprese in questa +interfaccia astratta (un caso tipico è l'impostazione della velocità di una +porta seriale, o le dimensioni di un framebuffer). + +Per questo motivo nell'architettura del sistema è stata prevista l'esistenza +di una funzione apposita, \func{ioctl}, con cui poter compiere le operazioni +specifiche di ogni dispositivo particolare, usando come riferimento il solito +file descriptor. Il prototipo di questa funzione è: \begin{prototype}{sys/ioctl.h}{int ioctl(int fd, int request, ...)} Manipola il dispositivo sottostante, usando il parametro \param{request} per - specificare l'operazione richiesta e il terzo parametro (usualmente di tipo + specificare l'operazione richiesta ed il terzo parametro (usualmente di tipo \param{char * argp} o \param{int argp}) per il trasferimento dell'informazione necessaria. @@ -1118,7 +1145,7 @@ per ogni singolo dispositivo. Il prototipo di questa funzione \item[\errcode{EINVAL}] gli argomenti \param{request} o \param{argp} non sono validi. \end{errlist} - ed inoltre \const{EBADF} e \const{EFAULT}.} + ed inoltre \errval{EBADF} e \errval{EFAULT}.} \end{prototype} La funzione serve in sostanza per fare tutte quelle operazioni che non si @@ -1144,17 +1171,22 @@ riferimento. Infatti anche se in genere i valori di \param{request} sono opportunamente differenziati a seconda del dispositivo\footnote{il kernel usa un apposito \textit{magic number} per distinguere ciascun dispositivo nella definizione delle macro da usare per \param{request}, in modo da essere - sicuri che essi siano sempre diversi, ed il loro uso causi al più un errore. - Si veda il capitolo quinto di \cite{LinDevDri} per una trattazione - dettagliata dell'argomento.} in alcuni casi, relativi a valori assegnati -prima che questa differenziazione diventasse pratica corrente si potrebbe -avere - -Per questo motivo non è possibile fare altro che darne una descrizione -generica; torneremo ad esaminare in seguito quelle relative ad alcuni casi -specifici (ad esempio la gestione dei terminali è effettuata attraverso -\func{ioctl} in quasi tutte le implementazioni di Unix), qui riportiamo solo i -valori che sono definiti per ogni file: + sicuri che essi siano sempre diversi, ed il loro uso per dispositivi diversi + causi al più un errore. Si veda il capitolo quinto di \cite{LinDevDri} per + una trattazione dettagliata dell'argomento.} così che la richiesta di +operazioni relative ad altri dispositivi usualmente provoca il ritorno della +funzione con una condizione di errore, in alcuni casi, relativi a valori +assegnati prima che questa differenziazione diventasse pratica corrente, si +potrebbero usare valori validi anche per il dispositivo corrente, con effetti +imprevedibili o indesiderati. + +Data la assoluta specificità della funzione, il cui comportamento varia da +dispositivo a dispositivo, non è possibile fare altro che dare una descrizione +sommaria delle sue caratteristiche; torneremo ad esaminare in seguito quelle +relative ad alcuni casi specifici (ad esempio la gestione dei terminali è +effettuata attraverso \func{ioctl} in quasi tutte le implementazioni di Unix), +qui riportiamo solo i valori di alcuni comandi che sono definiti per ogni +file: \begin{basedescript}{\desclabelwidth{2.0cm}} \item[\const{FIOCLEX}] Imposta il bit di \textit{close on exec}. \item[\const{FIONCLEX}] Cancella il bit di \textit{close on exec}.