X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=blobdiff_plain;f=fileunix.tex;h=56e70435f4d2934b1e1abdeffe54b4ce5e82e703;hp=8428e10ae4d9f0c11357a3fa2aadd63e21fa67c4;hb=1fe9dd622fcc8e8c83de032cf8679806cf52359b;hpb=30a6a42996cb5bf0d7c0b2b607743893dc964cdd diff --git a/fileunix.tex b/fileunix.tex index 8428e10..56e7043 100644 --- a/fileunix.tex +++ b/fileunix.tex @@ -221,7 +221,7 @@ sempre il file descriptor con il valore pi \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. \\ + \macro{O\_RDWR} & apre il file in lettura/scrittura. \\ \hline % modalità di apertura del file \hline \macro{O\_CREAT} & se il file non esiste verrà creato, con le regole di @@ -232,8 +232,8 @@ sempre il file descriptor con il valore pi \func{open} con \macro{EEXIST}. \\ \macro{O\_NONBLOCK} & apre il file in modalità non bloccante. Questo valore specifica anche una modalità di operazione (vedi sotto), e - comporta che \func{open} ritorni immediatamente (torneremo su - questo in \secref{sec:file_noblocking}). \\ + comporta che \func{open} ritorni immediatamente (l'opzione ha senso + solo per le fifo, torneremo questo in \secref{sec:ipc_named_pipe}). \\ \macro{O\_NOCTTY} & se \var{pathname} si riferisce ad un device di terminale, questo non diventerà il terminale di controllo, anche se il processo non ne ha ancora uno (si veda \secref{sec:sess_xxx}). \\ @@ -265,10 +265,11 @@ sempre il file descriptor con il valore pi file. Può causare corruzione del file con NFS se più di un processo scrive allo stesso tempo.\footnotemark\\ \macro{O\_NONBLOCK} & il file viene aperto in modalità non bloccante per - le operazioni di I/O: questo significa il fallimento di \func{read} in - assenza di dati da leggere e quello di \func{write} in caso di - impossibilità di scrivere immediatamente. L'opzione è effettiva solo per - le fifo e per alcuni file di dispositivo. \\ + le operazioni di I/O (che tratteremo in \secref{sec:file_noblocking}): + questo significa il fallimento di \func{read} in assenza di dati da + leggere e quello di \func{write} in caso di impossibilità di scrivere + immediatamente. Questa modalità ha senso solo per le fifo e per alcuni + file di dispositivo. \\ \macro{O\_NDELAY} & in Linux\footnotemark\ è sinonimo di \macro{O\_NONBLOCK}.\\ \macro{O\_ASYNC} & apre il file per l'I/O in modalità @@ -295,9 +296,9 @@ sempre il file descriptor con il valore pi di usare un file con un nome univoco e la funzione \func{link} per verificarne l'esistenza.} -\footnotetext[3]{Denial of Service, si chiamano così attacchi miranti ad - impedire un servizio causando una qualche forma di carico eccessivo per il - sistema, che resta bloccato nelle risposte all'attacco.} +\footnotetext[3]{\textit{Denial of Service}, si chiamano così attacchi miranti + ad impedire un servizio causando una qualche forma di carico eccessivo per + il sistema, che resta bloccato nelle risposte all'attacco.} \footnotetext[4]{il problema è che NFS non supporta la scrittura in append, ed il kernel deve simularla, ma questo comporta la possibilità di una race @@ -538,44 +539,42 @@ come valore di ritorno. Con i \textsl{file regolari} questa è l'unica situazione in cui si può avere un numero di byte letti inferiore a quello richiesto, ma questo non è vero quando si legge da un terminale, da una fifo o da una pipe. In tal caso -infatti, se non ci sono dati in ingresso, la \func{read} si blocca e ritorna -solo quando ne arrivano; se il numero di byte richiesti eccede quelli -disponibili la funzione ritorna comunque, ma con un numero di byte inferiore a -quelli richiesti. +infatti, se non ci sono dati in ingresso, la \func{read} si blocca (a meno di +non aver selezionato la modalità non bloccante, vedi +\secref{sec:file_noblocking}) e ritorna solo quando ne arrivano; se il numero +di byte richiesti eccede quelli disponibili la funzione ritorna comunque, ma +con un numero di byte inferiore a quelli richiesti. Lo stesso comportamento avviene caso di lettura dalla rete (cioè su un socket, -come vedremo in \secref{sec:sock_io_behav}), o per certi dispositivi, come le -unità a nastro, che restituiscono un singolo blocco di dati alla volta. +come vedremo in \secref{sec:sock_io_behav}), o per la lettura da certi file di +dispositivo, come le unità a nastro, che restituiscono sempre i dati ad un +singolo blocco alla volta. In realtà anche le due condizioni segnalate dagli errori \macro{EINTR} e \macro{EAGAIN} non sono errori. La prima si verifica quando la \func{read} è bloccata in attesa di dati in ingresso e viene interrotta da un segnale; in -tal caso l'azione da prendere è quella di rieseguire la funzione. Torneremo -sull'argomento in \secref{sec:sig_gen_beha}. - -La seconda si verifica quando il file è in modalità non bloccante e non ci -sono dati in ingresso: la funzione allora ritorna immediatamente con un errore -\macro{EAGAIN}\footnote{sotto BSD questo per questo errore viene usata la - costante \macro{EWOULDBLOCK}, in GNU/Linux questa è sinonima di - \macro{EAGAIN}.} che nel caso indica soltanto che occorrerà provare a -ripetere la lettura. - - -Nella seconda versione delle \textit{Single Unix +tal caso l'azione da prendere è quella di rieseguire la funzione. Torneremo in +dettaglio sull'argomento in \secref{sec:sig_gen_beha}. + +La seconda si verifica quando il file è in modalità non bloccante (vedi +\secref{sec:file_noblocking}) e non ci sono dati in ingresso: la funzione +allora ritorna immediatamente con un errore \macro{EAGAIN}\footnote{sotto BSD + questo per questo errore viene usata la costante \macro{EWOULDBLOCK}, in + Linux, con le glibc, questa è sinonima di \macro{EAGAIN}.} che nel caso +indica soltanto che occorrerà provare a ripetere la lettura. + +La funzione \func{read} è una delle system call fondamentali, esistenti fin +dagli albori di Unix, ma nella seconda versione delle \textit{Single Unix Specification}\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 - aggiunto con la versione 2.1.} (quello che viene chiamato normalmente Unix98, -vedi \secref{sec:intro_opengroup}) è stata introdotta la definizione di -un'altra funzione di lettura, \func{pread}, che diventa accessibile con la -definizione: -\begin{verbatim} - #define _XOPEN_SOURCE 500 -\end{verbatim} -il prototipo di questa funzione è: + aggiunto con la versione 2.1, in versioni precedenti sia del kernel che + delle librerie la funzione non è disponibile.} (quello che viene chiamato +normalmente Unix98, vedi \secref{sec:intro_opengroup}) è stata introdotta la +definizione di un'altra funzione di lettura, \func{pread}, il cui prototipo è: \begin{prototype}{unistd.h} {ssize\_t pread(int fd, void * buf, size\_t count, off\_t offset)} - + Cerca di leggere \var{count} byte dal file \var{fd}, a partire dalla posizione \var{offset}, nel buffer \var{buf}. @@ -583,10 +582,15 @@ Cerca di leggere \var{count} byte dal file \var{fd}, a partire dalla posizione in caso di errore, nel qual caso \var{errno} viene settata secondo i valori già visti per \func{read} e \func{lseek}.} \end{prototype} +\noindent che però diventa accessibile solo con la definizione della macro: +\begin{verbatim} + #define _XOPEN_SOURCE 500 +\end{verbatim} Questa funzione serve quando si vogliono leggere dati dal file senza modificarne la posizione corrente. È equivalente alla esecuzione di una -\func{read} e una \func{lseek}, ma permette di eseguire l'operazione +\func{read} seguita da una \func{lseek} che riporti al valore precedente la +posizione corrente sul file, ma permette di eseguire l'operazione atomicamente. Questo può essere importante quando la posizione sul file viene condivisa da processi diversi (vedi \secref{sec:file_sharing}). Il valore di \var{offset} fa sempre riferimento all'inizio del file. @@ -881,7 +885,8 @@ 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}. +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} @@ -889,18 +894,30 @@ nella \textit{file table}. \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 è: +Si noti che per quanto illustrato in\figref{fig:file_dup} i file descriptor +duplicati condivideranno eventuali lock, \textit{file status flag}, e +posizione corrente. Se ad esempio si esegue una \func{lseek} per modificare la +posizione su uno dei due file descriptor, essa risulterà modificata anche +sull'altro (dato che quello che viene modificato è lo stesso campo nella voce +della \textit{file table} a cui entrambi fanno riferimento). L'unica +differenza fra due file descriptor duplicati è che ciascuno avrà il suo +\textit{file descriptor flag}; a questo proposito va specificato che nel caso +di \func{dup} il flag di \textit{close on exec} viene sempre cancellato nella +copia. + +L'uso principale di questa funzione è 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 sull'argomento in \secref{sec:ipc_pipe_use}, +quando tratteremo le pipe). Per fare questo in genere occorre prima chiudere +il file che si vuole sostituire, cossicché il suo file descriptor possa esser +restituito alla chiamata di \func{dup}, come primo file descriptor +disponibile. + +Dato che questa è l'operazione più comune, è prevista una diversa versione +della funzione, \func{dup2}, che permette di specificare esplicitamente qual'è +il valore di file descriptor che si vuole avere come duplicato; il suo +prototipo è: \begin{prototype}{unistd.h}{int dup2(int oldfd, int newfd)} Rende \param{newfd} una copia del file descriptor \param{oldfd}. @@ -915,11 +932,13 @@ specificare esplicitamente il nuovo file descriptor; il suo prototipo descriptor aperti. \end{errlist}} \end{prototype} -\noindent la funzione chiude il file descriptor \param{newfd} se è aperto. +\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. 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}. +\secref{sec:file_fcntl}) con il parametro \macro{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}. La sola @@ -928,12 +947,6 @@ se 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 in \secref{sec:ipc_pipe_use} -quando tratteremo le pipe. - \subsection{La funzione \func{fcntl}} \label{sec:file_fcntl}