Completate le funzioni per la lettura e la scansione delle directory
authorSimone Piccardi <piccardi@gnulinux.it>
Mon, 30 Dec 2002 22:43:30 +0000 (22:43 +0000)
committerSimone Piccardi <piccardi@gnulinux.it>
Mon, 30 Dec 2002 22:43:30 +0000 (22:43 +0000)
filedir.tex

index 61e39aa08bc0961da309d618c5f3d8cc5d4f709c..8b522d6f78b927da1beed793b24bdb1f00df8541 100644 (file)
@@ -741,15 +741,15 @@ successiva.  I dati vengono memorizzati in una struttura \struct{dirent} (la
 cui definizione\footnote{la definizione è quella usata a Linux, che si trova
   nel file \file{/usr/include/bits/dirent.h}, essa non contempla la presenza
   del campo \var{d\_namlen} che indica la lunghezza del nome del file (ed
 cui definizione\footnote{la definizione è quella usata a Linux, che si trova
   nel file \file{/usr/include/bits/dirent.h}, essa non contempla la presenza
   del campo \var{d\_namlen} che indica la lunghezza del nome del file (ed
-  infatti la macro \macro{\_DIRENT\_HAVE\_D\_NAMLEN} non è definita.}  è
+  infatti la macro \macro{\_DIRENT\_HAVE\_D\_NAMLEN} non è definita).}  è
 riportata in \figref{fig:file_dirent_struct}). La funzione restituisce il
 puntatore alla struttura; si tenga presente però che quest'ultima è allocata
 riportata in \figref{fig:file_dirent_struct}). La funzione restituisce il
 puntatore alla struttura; si tenga presente però che quest'ultima è allocata
-staticamente, per cui viene sovrascritta tutte le volte che si ripete una
-lettura sullo stesso stream.
+staticamente, per cui viene sovrascritta tutte le volte che si ripete la
+lettura di una voce sullo stesso stream.
 
 
-Di questa funzione esiste anche una versione rientrante, \func{readdir\_r} che
-non usa una struttura allocata staticamente, e può essere utilizzata anche con
-i thread; il suo prototipo è:
+Di questa funzione esiste anche una versione rientrante, \func{readdir\_r},
+che non usa una struttura allocata staticamente, e può essere utilizzata anche
+con i thread; il suo prototipo è:
 \begin{functions}
   \headdecl{sys/types.h} \headdecl{dirent.h} 
   
 \begin{functions}
   \headdecl{sys/types.h} \headdecl{dirent.h} 
   
@@ -764,25 +764,29 @@ i thread; il suo prototipo 
 
 La funzione restituisce in \param{result} (come \textit{value result
   argument}) l'indirizzo dove sono stati salvati i dati, che di norma
 
 La funzione restituisce in \param{result} (come \textit{value result
   argument}) l'indirizzo dove sono stati salvati i dati, che di norma
-corriponde a quallo specificato dall'argomento \param{entry} (anche se non è
-assicurato che la funzione usi lo spazio fornito dall'utente).
+corriponde a quallo della struttura precedentemente allocata e specificata
+dall'argomento \param{entry} (anche se non è assicurato che la funzione usi lo
+spazio fornito dall'utente).
 
 I vari campi di \struct{dirent} contengono le informazioni relative alle voci
 
 I vari campi di \struct{dirent} contengono le informazioni relative alle voci
-presenti nella directory; i soli campi sempre presenti secondo lo standard
-POSIX sono \var{d\_name}, che contiene il nome del file nella forma di una
-stringa terminata da uno zero,\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.} e \var{d\_fileno} che contiene il numero
-di inode cui il file è associato (di solito corriponde al campo \var{st\_ino}
-di \struct{stat}); questo campo viene anche chiamato \var{d\_ino}, per
-compatibilità con la definizione usata da BSD.
+presenti nella directory; sia BSD che SVr4\footnote{POSIX prevede invece solo
+  la presenza del campo \var{d\_fileno}, identico \var{d\_ino}, che in Linux è
+  definito come alias di quest'ultimo. Il campo \var{d\_name} è considerato
+  dipendente dall'implementazione.} prevedono che siano sempre presenti il
+campo \var{d\_name}, che contiene il nome del file nella forma di una stringa
+terminata da uno zero,\footnote{lo standard POSIX non specifica una lunghezza,
+  ma solo un limite \const{NAME\_MAX}; in SVr4 la lunghezza del campo è
+  definta come \code{NAME\_MAX+1} che di norma porta al valore di 256 byte
+  usato anche in Linux.} ed il campo \var{d\_ino}, che contiene il numero di
+inode cui il file è associato (di solito corriponde al campo \var{st\_ino} di
+\struct{stat}).
 
 \begin{figure}[!htb]
   \footnotesize \centering
   \begin{minipage}[c]{15cm}
     \begin{lstlisting}[labelstep=0]{}%,frame=,indent=1cm]{}
 struct dirent {
 
 \begin{figure}[!htb]
   \footnotesize \centering
   \begin{minipage}[c]{15cm}
     \begin{lstlisting}[labelstep=0]{}%,frame=,indent=1cm]{}
 struct dirent {
-    ino_t d_fileno;                 /* inode number */
+    ino_t d_ino;                    /* inode number */
     off_t d_off;                    /* offset to the next dirent */
     unsigned short int d_reclen;    /* length of this record */
     unsigned char d_type;           /* type of file */
     off_t d_off;                    /* offset to the next dirent */
     unsigned short int d_reclen;    /* length of this record */
     unsigned char d_type;           /* type of file */
@@ -824,11 +828,12 @@ il nome del relativo campo; nel nostro caso sono definite le macro
   \label{tab:file_dtype_macro}
 \end{table}
 
   \label{tab:file_dtype_macro}
 \end{table}
 
-Il campo \var{d\_type} indica il tipo di file (fifo, directory, link
-simbolico, ecc.); i suoi possibili valori sono riportati in
-\tabref{tab:file_dtype_macro}; per la conversione da e verso l'analogo valore
-mantenuto dentro il campo \var{st\_mode} di \struct{stat} sono definite anche
-due macro di conversione \macro{IFTODT} e \macro{DTTOIF}:
+Per quanto riguarda il significato dei campi opzionali, il campo \var{d\_type}
+indica il tipo di file (fifo, directory, link simbolico, ecc.); i suoi
+possibili valori sono riportati in \tabref{tab:file_dtype_macro}; per la
+conversione da e verso l'analogo valore mantenuto dentro il campo
+\var{st\_mode} di \struct{stat} sono definite anche due macro di conversione
+\macro{IFTODT} e \macro{DTTOIF}:
 \begin{functions}
   \funcdecl{int IFTODT(mode\_t MODE)} Converte il tipo di file dal formato di
   \var{st\_mode} a quello di \var{d\_type}.
 \begin{functions}
   \funcdecl{int IFTODT(mode\_t MODE)} Converte il tipo di file dal formato di
   \var{st\_mode} a quello di \var{d\_type}.
@@ -837,10 +842,11 @@ due macro di conversione \macro{IFTODT} e \macro{DTTOIF}:
   \var{d\_type} a quello di \var{st\_mode}.
 \end{functions}
 
   \var{d\_type} a quello di \var{st\_mode}.
 \end{functions}
 
-Il campo \var{d\_off} contiene la posizione della successiva voce nella
-directory, mentre il campo \var{d\_reclen} la lunghezza totale della voce. Con
-questi campi diventa possibile spostarsi all'interno dello stream usando la
-funzione \func{seekdir},\footnote{sia questa funzione, che la corrispondente
+Il campo \var{d\_off} contiene invece la posizione della voce successiva della
+directory, mentre il campo \var{d\_reclen} la lunghezza totale della voce
+letta. Con questi due campi diventa possibile, determinando la posizione delle
+varie voci, spostarsi all'interno dello stream usando la funzione
+\func{seekdir},\footnote{sia questa funzione, che la corrispondente
   \func{telldir}, sono estensioni prese da BSD, non previste dallo standard
   POSIX.} il cui prototipo è:
 \begin{prototype}{dirent.h}{void seekdir(DIR *dir, off\_t offset)}
   \func{telldir}, sono estensioni prese da BSD, non previste dallo standard
   POSIX.} il cui prototipo è:
 \begin{prototype}{dirent.h}{void seekdir(DIR *dir, off\_t offset)}
@@ -861,8 +867,16 @@ legge la posizione corrente; il prototipo di quest'ultima 
     valore errrato per \param{dir}.}
 \end{prototype}
 
     valore errrato per \param{dir}.}
 \end{prototype}
 
-
-
+La sola funzione di posizionamento nello stream prevista dallo standard POSIX
+è \funcd{rewinddir}, che riporta la posizione a quella iniziale; il suo
+prototipo è:
+\begin{functions}
+  \headdecl{sys/types.h} \headdecl{dirent.h} 
+  
+  \funcdecl{void rewinddir(DIR *dir)}
+  
+  Si posiziona all'inzio di un \textit{directory stream}.
+\end{functions}
 
 
 Una volta completate le operazioni si può chiudere il \textit{directory
 
 
 Una volta completate le operazioni si può chiudere il \textit{directory
@@ -878,6 +892,68 @@ Una volta completate le operazioni si pu
     qual caso \var{errno} assume il valore \errval{EBADF}.}
 \end{functions}
 
     qual caso \var{errno} assume il valore \errval{EBADF}.}
 \end{functions}
 
+A parte queste funzioni di base in BSD 4.3 è stata introdotta un'altra
+funzione che permette di eseguire una scansione completa (con tanto di ricerca
+ed ordinamento) del contenuto di una directory; la funzione è
+\funcd{scandir}\footnote{in Linux questa funzione è stata introdotta fin dalle
+  libc4.} ed il suo prototipo è:
+\begin{prototype}{dirent.h}{int scandir(const char *dir, 
+    struct dirent ***namelist, int(*select)(const struct dirent *),
+    int(*compar)(const struct dirent **, const struct dirent **))} 
+  
+  Esegue una scansione di un \textit{directory stream}.
+  
+  \bodydesc{La funzione restituisce in caso di successo il numero di voci
+    trovate, e -1 altrimenti.}
+\end{prototype}
+
+Al solito, per la presenza fra gli argomenti di due puntatori a funzione, il
+prototipo non è molto comprensibile; queste funzioni però sono quelle che
+controllano rispettivamente la selezione di una voce (\param{select}) e
+l'ordinamento di tutte le voci selezionate (\param{compar}). 
+
+La funzione legge tutte le voci della directory indicata dall'argomento
+\param{dir}, passando ciascuna di esse come argomento alla funzione di
+\param{select}; se questa ritorna un valore diverso da zero la voce viene
+inserita in una struttura allocata dinamicamante con \func{malloc}, qualora si
+specifichi un valore \val{NULL} per \func{select} vengono selezionate tutte le
+voci. Tutte le voci selezionate vengono poi inserite un una lista (anch'essa
+allocata con \func{malloc}, che viene riordinata tramite \func{qsort} usando
+la funzione \param{compar} come criterio di ordinamento; alla fine l'indirizzo
+della lista ordinata è restituito nell'argomento \param{namelist}.
+
+Per l'ordinamento sono disponibili anche due funzioni predefinite,
+\funcd{alphasort} e \funcd{versionsort}, i cui prototipi sono:
+\begin{functions}
+  \headdecl{dirent.h} 
+  
+  \funcdecl{int alphasort(const void *a, const void *b)} 
+
+  \funcdecl{int versionsort(const void *a, const void *b)} 
+  
+  Funzioni per l'ordinamento delle voci di \textit{directory stream}.
+  
+  \bodydesc{Le funzioni restituiscono un valore minore, uguale o maggiore di
+    zero qualora il primo argomento sia rispettivamente minore, uguale o
+    maggiore del secondo.}
+\end{functions}
+
+
+La funzione \func{alphasort} deriva da BSD ed è presente in Linux fin dalle
+libc4\footnote{la versione delle libc4 e libc5 usa però come argomenti dei
+  puntatori a delle strutture \struct{dirent}; le glibc usano il prototipo
+  originario di BSD, mostrato anche nella definizione, che prevede puntatori a
+  \ctyp{void}.}  e deve essere specificata come argomento \param{compare} per
+ottenere un ordinamento alfabetico (secondo il valore del campo \var{d\_name}
+delle varie voci). Le \acr{glibc} prevedono come estensione\footnote{le glibc,
+  a partire dalla versione 2.1, effettuano anche l'ordinamento alfabetico
+  tenendo conto delle varie localizzazioni, usando \func{strcoll} al posto di
+  \func{strcmp}.} anche \func{versionsort}, che ordina i nomi tenendo conto
+del numero di versione (cioè qualcosa per cui \file{file10} viene comunque
+dopo \func{file4}.)
+
+
+
 
 \subsection{La directory di lavoro}
 \label{sec:file_work_dir}
 
 \subsection{La directory di lavoro}
 \label{sec:file_work_dir}
@@ -1645,21 +1721,21 @@ Esistono varie estensioni a questo modello,\footnote{come le \textit{Access
   come il \textit{mandatory access control} di SE-Linux.} ma nella maggior
 parte dei casi il meccanismo standard è più che sufficiente a soddisfare tutte
 le necessità più comuni.  I tre permessi di base associati ad ogni file sono:
   come il \textit{mandatory access control} di SE-Linux.} ma nella maggior
 parte dei casi il meccanismo standard è più che sufficiente a soddisfare tutte
 le necessità più comuni.  I tre permessi di base associati ad ogni file sono:
-\begin{itemize}
+\begin{itemize*}
 \item il permesso di lettura (indicato con la lettera \texttt{r}, dall'inglese
   \textit{read}).
 \item il permesso di scrittura (indicato con la lettera \texttt{w},
   dall'inglese \textit{write}).
 \item il permesso di esecuzione (indicato con la lettera \texttt{x},
   dall'inglese \textit{execute}).
 \item il permesso di lettura (indicato con la lettera \texttt{r}, dall'inglese
   \textit{read}).
 \item il permesso di scrittura (indicato con la lettera \texttt{w},
   dall'inglese \textit{write}).
 \item il permesso di esecuzione (indicato con la lettera \texttt{x},
   dall'inglese \textit{execute}).
-\end{itemize}
+\end{itemize*}
 mentre i tre livelli su cui sono divisi i privilegi sono:
 mentre i tre livelli su cui sono divisi i privilegi sono:
-\begin{itemize}
+\begin{itemize*}
 \item i privilegi per l'utente proprietario del file.
 \item i privilegi per un qualunque utente faccia parte del gruppo cui
   appartiene il file.
 \item i privilegi per tutti gli altri utenti.
 \item i privilegi per l'utente proprietario del file.
 \item i privilegi per un qualunque utente faccia parte del gruppo cui
   appartiene il file.
 \item i privilegi per tutti gli altri utenti.
-\end{itemize}
+\end{itemize*}
 
 L'insieme dei permessi viene espresso con un numero a 12 bit; di questi i nove
 meno significativi sono usati a gruppi di tre per indicare i permessi base di
 
 L'insieme dei permessi viene espresso con un numero a 12 bit; di questi i nove
 meno significativi sono usati a gruppi di tre per indicare i permessi base di
@@ -1914,11 +1990,11 @@ invece assunto un uso importante per le directory;\footnote{lo \textsl{sticky
 impostato un file potrà essere rimosso dalla directory soltanto se l'utente ha
 il permesso di scrittura su di essa ed inoltre è vera una delle seguenti
 condizioni:
 impostato un file potrà essere rimosso dalla directory soltanto se l'utente ha
 il permesso di scrittura su di essa ed inoltre è vera una delle seguenti
 condizioni:
-\begin{itemize}
+\begin{itemize*}
 \item l'utente è proprietario del file
 \item l'utente è proprietario della directory
 \item l'utente è l'amministratore 
 \item l'utente è proprietario del file
 \item l'utente è proprietario della directory
 \item l'utente è l'amministratore 
-\end{itemize}
+\end{itemize*}
 un classico esempio di directory che ha questo bit impostato è \file{/tmp}, i
 permessi infatti di solito sono i seguenti:
 \begin{verbatim}
 un classico esempio di directory che ha questo bit impostato è \file{/tmp}, i
 permessi infatti di solito sono i seguenti:
 \begin{verbatim}
@@ -1946,11 +2022,11 @@ per la creazione di nuove directory (procedimento descritto in
 Lo standard POSIX prescrive che l'\acr{uid} del nuovo file corrisponda
 all'userid effettivo del processo che lo crea; per il \acr{gid} invece prevede
 due diverse possibilità:
 Lo standard POSIX prescrive che l'\acr{uid} del nuovo file corrisponda
 all'userid effettivo del processo che lo crea; per il \acr{gid} invece prevede
 due diverse possibilità:
-\begin{itemize}
+\begin{itemize*}
 \item il \acr{gid} del file corrisponde al groupid effettivo del processo.
 \item il \acr{gid} del file corrisponde al \acr{gid} della directory in cui
   esso è creato.
 \item il \acr{gid} del file corrisponde al groupid effettivo del processo.
 \item il \acr{gid} del file corrisponde al \acr{gid} della directory in cui
   esso è creato.
-\end{itemize}
+\end{itemize*}
 in genere BSD usa sempre la seconda possibilità, che viene per questo chiamata
 semantica BSD. Linux invece segue quella che viene chiamata semantica SVr4; di
 norma cioè il nuovo file viene creato, seguendo la prima opzione, con il
 in genere BSD usa sempre la seconda possibilità, che viene per questo chiamata
 semantica BSD. Linux invece segue quella che viene chiamata semantica SVr4; di
 norma cioè il nuovo file viene creato, seguendo la prima opzione, con il