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
-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}
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
-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 {
- 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 */
\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}.
\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)}
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
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}
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}).
-\end{itemize}
+\end{itemize*}
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.
-\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
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
-\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}
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.
-\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