From: Simone Piccardi Date: Sat, 28 Dec 2002 12:47:27 +0000 (+0000) Subject: Riscritta opendir e spiegata dirent X-Git-Url: https://gapil.gnulinux.it/gitweb/?a=commitdiff_plain;h=8b05cf6a5144139ae1cefc39094e129dfc1dca34;p=gapil.git Riscritta opendir e spiegata dirent --- diff --git a/filedir.tex b/filedir.tex index 2ad3679..bb7f8a6 100644 --- a/filedir.tex +++ b/filedir.tex @@ -396,8 +396,8 @@ direttamente sul suo contenuto. Si noti che non si è specificato il comportamento delle funzioni che operano con i file descriptor, in quanto la risoluzione del link simbolico viene in genere effettuata dalla funzione che restituisce il file descriptor -(normalmente la \func{open}) e tutte le operazioni seguenti fanno riferimento -solo a quest'ultimo. +(normalmente la \func{open}, vedi \secref{sec:file_open}) e tutte le +operazioni seguenti fanno riferimento solo a quest'ultimo. Dato che, come indicato in \tabref{tab:file_symb_effect}, funzioni come la \func{open} seguono i link simbolici, occorrono funzioni apposite per accedere @@ -438,12 +438,13 @@ Un caso comune che si pu cosiddetti \textit{loop}. La situazione è illustrata in \figref{fig:file_link_loop}, che riporta la struttura della directory \file{/boot}. Come si vede si è creato al suo interno un link simbolico che -punta di nuovo a \file{/boot}.\footnote{Questo tipo di loop è stato effettuato - per poter permettere a \cmd{grub} (un bootloader in grado di leggere - direttamente da vari filesystem il file da lanciare come sistema operativo) - di vedere i file in questa directory con lo stesso path con cui verrebbero - visti dal sistema operativo, anche se essi si trovano, come è solito, su una - partizione separata (e che \cmd{grub} vedrebbe come radice).} +punta di nuovo a \file{/boot}.\footnote{il loop mostrato in + \figref{fig:file_link_loop} è un usato per poter permettere a \cmd{grub} (un + bootloader in grado di leggere direttamente da vari filesystem il file da + lanciare come sistema operativo) di vedere i file contenuti nella directory + \file{/boot} con lo stesso pathname con cui verrebbero visti dal sistema + operativo, anche se essi si trovano, come accade spesso, su una partizione + separata (che \cmd{grub}, all'avvio, vede come radice).} Questo può causare problemi per tutti quei programmi che effettuano la scansione di una directory senza tener conto dei link simbolici, ad esempio se @@ -653,18 +654,27 @@ modificati dal valore di \var{umask}. \subsection{Accesso alle directory} \label{sec:file_dir_read} -Benché le directory siano oggetti del filesystem come tutti gli altri non ha -senso aprirle come fossero dei file di dati; per questo solo il kernel può -scrivere direttamente il contenuto di una directory (onde evitare -inconsistenze all'interno del filesystem), mentre i processi devono creare i -file usando le apposite funzioni. Può però essere utile potere leggere il -contenuto di una directory, ad esempio per fare la lista dei file che contiene -o per delle ricerche. - -Per far questo lo standard POSIX\footnote{le funzioni sono previste pure in - BSD e SVID.} ha introdotto i cosiddetti \textit{directory streams} (chiamati -così per l'analogia con i file stream di \capref{cha:files_std_interface}) ed -una serie di funzioni per la loro gestione. La prima di queste è +Benché le directory alla fine non siano altro che dei file che contengono +delle liste di nomi ed inode, per il ruolo che rivestono nella struttura del +sistema, non possono essere trattate come dei normali file di dati. Ad +esempio, onde evitare inconsistenze all'interno del filesystem, solo il kernel +può scrivere il contenuto di una directory, e non può essere un processo a +inserirvi direttamente delle voci con le usuali funzioni di scrittura. + +Ma se la scrittura e l'aggiornamento dei dati delle directory è compito del +kernel, sono molte le situazioni in cui i processi necessitano di poterne +leggere il contenuto. Benché questo possa essere fatto direttamente (vedremo +in \secref{sec:file_open} che è possibile aprire una directory come se fosse +un file, anche se solo in sola lettura) in generale il formato con cui esse +sono scritte può dipendere dal tipo di filesystem, tanto che, come riportato +in \tabref{tab:file_file_operations}, il VFS del kernel prevede una apposita +funzione per la lettura delle directory. + +Tutto questo si riflette nello standard POSIX\footnote{le funzioni sono + previste pure in BSD e SVID.} che ha introdotto una apposita interfaccia per +la lettura delle directory, basata sui cosiddetti \textit{directory streams} +(chiamati così per l'analogia con i file stream dell'interfaccia standard di +\capref{cha:files_std_interface}). La prima funzione di questa interfaccia è \funcd{opendir}, il cui prototipo è: \begin{functions} \headdecl{sys/types.h} \headdecl{dirent.h} @@ -680,17 +690,15 @@ una serie di funzioni per la loro gestione. La prima di queste \end{functions} La funzione apre un \textit{directory stream} per la directory -\param{dirname}, ritornando il puntatore alla relativa struttura \type{DIR} -(questo è un tipo opaco\index{tipo!opaco} usato dalle librerie per gestire i -\textit{directory stream}) da usare per le successive operazioni, posizionando -lo stream sulla prima voce contenuta nella directory. +\param{dirname}, ritornando il puntatore ad un oggetto di tipo \type{DIR} (che +è il tipo opaco\index{tipo!opaco} usato dalle librerie per gestire i +\textit{directory stream}) da usare per tutte le operazioni successive, la +funzione inoltre posiziona lo stream sulla prima voce contenuta nella +directory. Dato che le directory sono comunque dei file, in alcuni casi può servire -conoscere il \textit{file descriptor} (tratteremo i \textit{file descriptor} -in \capref{cha:file_unix_interface}) sottostante un \textit{directory stream}, -ad esempio per utilizzarlo con la funzione \func{fchdir} per cambiare la -directory di lavoro (vedi \secref{sec:file_work_dir}) a quella relativa allo -stream stesso. A questo scopo si può usare la funzione \funcd{dirfd}, il cui +conoscere il \textit{file descriptor} associato ad un \textit{directory + stream}, a questo scopo si può usare la funzione \funcd{dirfd}, il cui prototipo è: \begin{functions} \headdecl{sys/types.h} \headdecl{dirent.h} @@ -707,7 +715,10 @@ La funzione\footnote{questa funzione POSIX, introdotta con BSD 4.3-Reno; è presente in Linux con le libc5 (a partire dalla versione 5.1.2) e con le \acr{glibc}.} restituisce il file descriptor associato al \textit{directory stream} \param{dir}, essa è -disponibile solo definendo \macro{\_BSD\_SOURCE} o \macro{\_SVID\_SOURCE}. +disponibile solo definendo \macro{\_BSD\_SOURCE} o \macro{\_SVID\_SOURCE}. Di +solito si utilizza questa funzione in abbinamento alla funzione \func{fchdir} +per cambiare la directory di lavoro (vedi \secref{sec:file_work_dir}) a quella +relativa allo stream che si sta esaminando. La lettura di una voce nella directory viene effettuata attraverso la funzione \funcd{readdir}; il suo prototipo è: @@ -727,10 +738,10 @@ La lettura di una voce nella directory viene effettuata attraverso la funzione La funzione legge la voce corrente nella directory, posizionandosi sulla voce successiva. I dati vengono memorizzati in una struttura \struct{dirent} (la -cui definizione è riportata in \figref{fig:file_dirent_struct}). La funzione -restituisce il puntatore alla struttura; si tenga presente però che questa -viene sovrascritta tutte le volte che si ripete una lettura sullo stesso -stream. +cui definizione in Linux è riportata in \figref{fig:file_dirent_struct}). La +funzione restituisce il puntatore alla struttura; si tenga presente però che +quest'ultima viene sovrascritta tutte le volte che si ripete una lettura sullo +stesso stream. \begin{figure}[!htb] \footnotesize \centering @@ -751,6 +762,41 @@ struct dirent { \label{fig:file_dirent_struct} \end{figure} +I vari campi contengono le informazioni relative ai file della directory; il +solo campo obbligatorio secondo lo standard POSIX è \var{d\_name}, che +contiene il nome del file nella forma di una stringa terminata da uno zero, la +cui lunghezza è riportata nel campo \var{d\_reclen}.\footnote{lo standard + POSIX non specifica una lunghezza, ma solo un limite \const{NAME\_MAX}, + anche se di norma il valore massimo per un nome è di 256 byte.} + +Il campo \var{d\_ino} contiene il numero di inode cui il file è associato ed +il campo \var{d\_type} il tipo di file (fifo, directory, link simbolico, +ecc.). Entrambi questi campi derivano da BSD e non appartengono allo standard; +la presenza del tipo di file è segnalata dalla macro +\macro{\_DIRENT\_HAVE\_D\_TYPE}; i possibili valori del campo \var{d\_type} +sono riportati in \tabref{tab:file_dtype_macro}. + +\begin{table}[htb] + \centering + \footnotesize + \begin{tabular}[c]{|l|l|} + \hline + \textbf{Valore} & \textbf{Significato} \\ + \hline + \hline + \const{DT\_UNKNOWN} & tipo sconosciuto. \\ + \const{DT\_REG} & file normale. \\ + \const{DT\_DIR} & directory. \\ + \const{DT\_FIFO} & fifo. \\ + \const{DT\_SOCK} & socket. \\ + \const{DT\_CHR} & dispositivo a caratteri. \\ + \const{DT\_BLK} & dispositivo a blocchi. \\ + \hline + \end{tabular} + \caption{Costanti che indicano i vari tipi di file nel campo \var{d\_type} + della struttura \struct{dirent}.} + \label{tab:file_dtype_macro} +\end{table}