From 9fd07acb47a0dddaff1769bdec46ffd760c7f0fb Mon Sep 17 00:00:00 2001 From: Simone Piccardi Date: Sat, 30 Jul 2011 17:07:34 +0000 Subject: [PATCH] Aggiornamento e revisione della sezione sulla scansione delle directory, aggiornamento delle feature macro. --- filedir.tex | 285 +++++++++++++++++++++++++++-------------------- fileunix.tex | 18 +-- intro.tex | 36 ++++-- listati/dirent.c | 5 +- listati/my_ls.c | 3 +- 5 files changed, 201 insertions(+), 146 deletions(-) diff --git a/filedir.tex b/filedir.tex index 5e7c0b6..814f6d4 100644 --- a/filedir.tex +++ b/filedir.tex @@ -527,7 +527,9 @@ elenchi di nomi ed \itindex{inode} \textit{inode}, non è possibile trattarle come file ordinari e devono essere create direttamente dal kernel attraverso una opportuna system call.\footnote{questo è quello che permette anche, attraverso l'uso del VFS, l'utilizzo di diversi formati per la gestione dei - suddetti elenchi.} La funzione usata per creare una directory è + suddetti elenchi, dalle semplici liste a strutture complesse come alberi + binari, hash, ecc. che consentono una ricerca veloce quando il numero di + file è molto grande.} La funzione usata per creare una directory è \funcd{mkdir}, ed il suo prototipo è: \begin{functions} \headdecl{sys/stat.h} @@ -794,12 +796,13 @@ sono scritte può dipendere dal tipo di filesystem, tanto che, come riportato in tab.~\ref{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 stream} -(chiamati così per l'analogia con i file stream dell'interfaccia standard ANSI -C di cap.~\ref{cha:files_std_interface}). La prima funzione di questa -interfaccia è \funcd{opendir}, il cui prototipo è: +Tutto questo si riflette nello standard POSIX\footnote{le funzioni erano + presenti in SVr4 e 4.3BSD, la loro specifica è riportata in POSIX.1-2001.} +che ha introdotto una apposita interfaccia per la lettura delle directory, +basata sui cosiddetti \textit{directory stream} (chiamati così per l'analogia +con i file stream dell'interfaccia standard ANSI C di +cap.~\ref{cha:files_std_interface}). La prima funzione di questa interfaccia è +\funcd{opendir}, il cui prototipo è: \begin{functions} \headdecl{sys/types.h} \headdecl{dirent.h} @@ -818,12 +821,24 @@ La funzione apre un \textit{directory stream} per la directory è il \index{tipo!opaco} 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} associato ad un \textit{directory - stream}, a questo scopo si può usare la funzione \funcd{dirfd}, il cui -prototipo è: +directory. + +Si tenga presente che comunque la funzione opera associando il +\textit{directory stream} ad un opportuno file descriptor sottostante, sul +quale vengono compiute le operazioni. Questo viene sempre aperto impostando il +flag di \itindex{close-on-exec} \textit{close-on-exec}, così da evitare che +resti aperto in caso di esecuzione di un altro programma. + +Nel caso in cui sia necessario conoscere il \textit{file descriptor} associato +ad un \textit{directory stream} si può usare la funzione +\funcd{dirfd},\footnote{questa funzione è una estensione introdotta con BSD + 4.3-Reno ed è presente in Linux con le libc5 (a partire dalla versione + 5.1.2) e con le \acr{glibc} ma non presente in POSIX fino alla revisione + POSIX.1-2008, per questo per poterla utilizzare fino alla versione 2.10 + delle \acr{glibc} era necessario definire le macro \macro{\_BSD\_SOURCE} o + \macro{\_SVID\_SOURCE}, dalla versione 2.10 si possono usare anche + \texttt{\macro{\_POSIX\_C\_SOURCE} >= 200809L} o + \texttt{\macro{\_XOPEN\_SOURCE} >= 700}.} il cui prototipo è: \begin{functions} \headdecl{sys/types.h} \headdecl{dirent.h} @@ -835,26 +850,26 @@ prototipo è: caso di successo e -1 in caso di errore.} \end{functions} -La funzione\footnote{questa funzione è una estensione di BSD non presente in - 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}. Di -solito si utilizza questa funzione in abbinamento alla funzione \func{fchdir} -per cambiare la directory di lavoro (vedi sez.~\ref{sec:file_work_dir}) a -quella relativa allo stream che si sta esaminando. +La funzione restituisce il file descriptor associato al \textit{directory + stream} \param{dir}. Di solito si utilizza questa funzione in abbinamento a +funzioni che operano sui file descriptor, ad esempio si potrà usare +\func{fstat} per ottenere le proprietà della directory, o \func{fchdir} per +spostare su di essa la directory di lavoro (vedi +sez.~\ref{sec:file_work_dir}). Viceversa se si è aperto un file descriptor corrispondente ad una directory è possibile associarvi un \textit{directory stream} con la funzione -\funcd{fopendir},\footnote{questa funzione è però disponibile solo a partire - dalla versione 2.4 delle \acr{glibc}, e pur essendo candidata per - l'inclusione nella successiva revisione dello standard POSIX.1-2001, non è - ancora presente in nessuna specifica formale.} il cui prototipo è: +\funcd{fdopendir},\footnote{questa funzione è però disponibile solo a partire + dalla versione 2.4 delle \acr{glibc}, ed è stata introdotta nello standard + POSIX solo a partire dalla revisione POSIX.1-2008, prima della versione 2.10 + delle \acr{glibc} per poterla utilizzare era necessario definire la macro + \macro{\_GNU\_SOURCE}, dalla versione 2.10 si possono usare anche + \texttt{\macro{\_POSIX\_C\_SOURCE} >= 200809L} o \texttt{\_XOPEN\_SOURCE >= + 700} .} il cui prototipo è: \begin{functions} - \headdecl{sys/types.h} - \headdecl{dirent.h} + \headdecl{sys/types.h} \headdecl{dirent.h} - \funcdecl{DIR * fopendir(int fd)} + \funcdecl{DIR * fdopendir(int fd)} Associa un \textit{directory stream} al file descriptor \param{fd}. @@ -865,14 +880,22 @@ possibile associarvi un \textit{directory stream} con la funzione La funzione è identica a \func{opendir}, ma ritorna un \textit{directory stream} facendo riferimento ad un file descriptor \param{fd} che deve essere -stato aperto in precedenza e la funzione darà un errore qualora questo non -corrisponda ad una directory. Una volta utilizzata il file descriptor verrà -usato dalle funzioni che operano sul \textit{directory stream} e non deve -essere più utilizzato direttamente all'interno del proprio programma. +stato aperto in precedenza; la funzione darà un errore qualora questo non +corrisponda ad una directory. L'uso di questa funzione permette di rispondere +agli stessi requisiti delle funzioni ``\textit{at}'' che vedremo in +sez.~\ref{sec:file_openat}. + +Una volta utilizzata il file descriptor verrà usato internamente dalle +funzioni che operano sul \textit{directory stream} e non dovrà essere più +utilizzato all'interno del proprio programma; in particolare dovrà essere +chiuso con \func{closedir} e non direttamente. Si tenga presente inoltre che +\func{fdopendir} non modifica lo stato di un eventuale flag di +\itindex{close-on-exec} \textit{close-on-exec}, che pertanto dovrà essere +impostato esplicitamente in fase di apertura del file descriptor. Una volta che si sia aperto un \textit{directory stream} la lettura del contenuto della directory viene effettuata attraverso la funzione -\funcd{readdir}, il suo prototipo è: +\funcd{readdir}; il suo prototipo è: \begin{functions} \headdecl{sys/types.h} \headdecl{dirent.h} @@ -881,10 +904,10 @@ contenuto della directory viene effettuata attraverso la funzione Legge una voce dal \textit{directory stream}. \bodydesc{La funzione restituisce il puntatore alla struttura contenente i - dati in caso di successo e \val{NULL} altrimenti, in caso di descrittore - non valido \var{errno} assumerà il valore \errval{EBADF}, il valore - \val{NULL} viene restituito anche quando si raggiunge la fine dello - stream.} + dati in caso di successo e \val{NULL} altrimenti, in caso di + \textit{directory stream} non valido \var{errno} assumerà il valore + \errval{EBADF}, il valore \val{NULL} viene restituito anche quando si + raggiunge la fine dello stream.} \end{functions} La funzione legge la voce corrente nella directory, posizionandosi sulla voce @@ -892,20 +915,34 @@ successiva. Pertanto se si vuole leggere l'intero contenuto di una directory occorrerà ripetere l'esecuzione della funzione fintanto che non si siano esaurite tutte le voci in essa presenti. -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 infatti - la macro \macro{\_DIRENT\_HAVE\_D\_NAMLEN} non è definita).} è riportata in -fig.~\ref{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 la lettura di una voce -sullo stesso \textit{directory stream}. +\begin{figure}[!htb] + \footnotesize \centering + \begin{minipage}[c]{15cm} + \includestruct{listati/dirent.c} + \end{minipage} + \normalsize + \caption{La struttura \structd{dirent} per la lettura delle informazioni dei + file.} + \label{fig:file_dirent_struct} +\end{figure} + +I dati vengono memorizzati in una struttura \struct{dirent}, la cui +definizione è riportata in fig.~\ref{fig:file_dirent_struct}.\footnote{la + definizione è quella usata da 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.} 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 la lettura di una voce sullo stesso \textit{directory + stream}. Di questa funzione esiste anche una versione \index{funzioni!rientranti} -rientrante, \func{readdir\_r}, che non usa una struttura allocata -staticamente, e può essere utilizzata anche con i \itindex{thread} -\textit{thread}, il suo prototipo è: +rientrante, \func{readdir\_r},\footnote{per usarla è necessario definire una + qualunque delle macro \texttt{\macro{\_POSIX\_C\_SOURCE} >= 1}, + \macro{\_XOPEN\_SOURCE}, \macro{\_BSD\_SOURCE}, \macro{\_SVID\_SOURCE}, + \macro{\_POSIX\_SOURCE}.} che non usa una struttura allocata staticamente, e +può essere utilizzata anche con i \itindex{thread} \textit{thread}, il suo +prototipo è: \begin{functions} \headdecl{sys/types.h} \headdecl{dirent.h} @@ -921,38 +958,28 @@ staticamente, e può essere utilizzata anche con i \itindex{thread} La funzione restituisce in \param{result} (come \itindex{value~result~argument} \textit{value result argument}) l'indirizzo dove sono stati salvati i dati, che di norma corrisponde a quello della -struttura precedentemente allocata e specificata dall'argomento \param{entry} -(anche se non è assicurato che la funzione usi lo spazio fornito dall'utente). - -\begin{figure}[!htb] - \footnotesize \centering - \begin{minipage}[c]{15cm} - \includestruct{listati/dirent.c} - \end{minipage} - \normalsize - \caption{La struttura \structd{dirent} per la lettura delle informazioni dei - file.} - \label{fig:file_dirent_struct} -\end{figure} +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; sia BSD che SVr4\footnote{lo standard 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 +presenti nella directory; sia BSD che SVr4 prevedono che siano sempre presenti +il campo \var{d\_name},\footnote{lo standard 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.} 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 è definita 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 \itindex{inode} \textit{inode} cui il file è associato (di solito -corrisponde al campo \var{st\_ino} di \struct{stat}). +di \textit{inode} cui il file è associato e corrisponde al campo \var{st\_ino} +di \struct{stat}. -La presenza di ulteriori campi opzionali è segnalata dalla definizione di -altrettante macro nella forma \code{\_DIRENT\_HAVE\_D\_XXX} dove \code{XXX} è -il nome del relativo campo; nel nostro caso sono definite le macro -\macro{\_DIRENT\_HAVE\_D\_TYPE}, \macro{\_DIRENT\_HAVE\_D\_OFF} e -\macro{\_DIRENT\_HAVE\_D\_RECLEN}. +La presenza di ulteriori campi opzionali oltre i due citati è segnalata dalla +definizione di altrettante macro nella forma \code{\_DIRENT\_HAVE\_D\_XXX} +dove \code{XXX} è il nome del relativo campo; nel caso di Linux sono pertanto +definite le macro \macro{\_DIRENT\_HAVE\_D\_TYPE}, +\macro{\_DIRENT\_HAVE\_D\_OFF} e \macro{\_DIRENT\_HAVE\_D\_RECLEN}, mentre non +è definita la macro \macro{\_DIRENT\_HAVE\_D\_NAMLEN}. \begin{table}[htb] \centering @@ -965,6 +992,7 @@ il nome del relativo campo; nel nostro caso sono definite le macro \const{DT\_UNKNOWN} & Tipo sconosciuto.\\ \const{DT\_REG} & File normale.\\ \const{DT\_DIR} & Directory.\\ + \const{DT\_LNK} & Link simbolico.\\ \const{DT\_FIFO} & Fifo.\\ \const{DT\_SOCK} & Socket.\\ \const{DT\_CHR} & Dispositivo a caratteri.\\ @@ -977,13 +1005,20 @@ il nome del relativo campo; nel nostro caso sono definite le macro \end{table} 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\footnote{fino alla versione 2.1 delle \acr{glibc} questo - campo, pur presente nella struttura, non era implementato, e resta sempre al - valore \const{DT\_UNKNOWN}.} sono riportati in -tab.~\ref{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}: +indica il tipo di file (se fifo, directory, link simbolico, ecc.), e consente +di evitare una successiva chiamata a \func{lstat} per determinarlo. I suoi +possibili valori sono riportati in tab.~\ref{tab:file_dtype_macro}. Si tenga +presente che questo valore è disponibile solo per i filesystem che ne +supportano la restituzione (fra questi i più noti sono \textsl{btrfs}, +\textsl{ext2}, \textsl{ext3}, e \textsl{ext4}), per gli altri si otterrà +sempre il valore \const{DT\_UNKNOWN}.\footnote{inoltre fino alla versione 2.1 + delle \acr{glibc}, pur essendo il campo \var{d\_type} presente, il suo uso + non era implementato, e veniva restituito comunque il valore + \const{DT\_UNKNOWN}.} + +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}. @@ -997,8 +1032,10 @@ 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 \funcd{seekdir},\footnote{sia questa funzione che \func{telldir}, sono - estensioni prese da BSD, non previste dallo standard POSIX.} il cui -prototipo è: + estensioni prese da BSD, ed introdotte nello standard POSIX solo a partire + dalla revisione POSIX.1-2001, per poterle utilizzare deve essere definita + una delle macro \macro{\_XOPEN\_SOURCE}, \macro{\_BSD\_SOURCE} o + \macro{\_SVID\_SOURCE}.} il cui prototipo è: \begin{prototype}{dirent.h}{void seekdir(DIR *dir, off\_t offset)} Cambia la posizione all'interno di un \textit{directory stream}. \end{prototype} @@ -1007,8 +1044,11 @@ La funzione non ritorna nulla e non segnala errori, è però necessario che il valore dell'argomento \param{offset} sia valido per lo stream \param{dir}; esso pertanto deve essere stato ottenuto o dal valore di \var{d\_off} di \struct{dirent} o dal valore restituito dalla funzione \funcd{telldir}, che -legge la posizione corrente; il prototipo di quest'ultima è: -\begin{prototype}{dirent.h}{off\_t telldir(DIR *dir)} +legge la posizione corrente; il prototipo di quest'ultima è:\footnote{prima + delle \acr{glibc} 2.1.1 la funzione restituiva un valore di tipo + \type{off\_t}, sostituito a partire dalla versione 2.1.2 da \ctyp{long} per + conformità a POSIX.1-2001.} +\begin{prototype}{dirent.h}{long telldir(DIR *dir)} Ritorna la posizione corrente in un \textit{directory stream}. \bodydesc{La funzione restituisce la posizione corrente nello stream (un @@ -1017,9 +1057,9 @@ legge la posizione corrente; il prototipo di quest'ultima è: valore errato 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 è: +La sola funzione di posizionamento nello stream prevista originariamente dallo +standard POSIX è \funcd{rewinddir}, che riporta la posizione a quella +iniziale; il suo prototipo è: \begin{functions} \headdecl{sys/types.h} \headdecl{dirent.h} @@ -1028,9 +1068,9 @@ prototipo è: Si posiziona all'inizio di un \textit{directory stream}. \end{functions} - Una volta completate le operazioni si può chiudere il \textit{directory - stream} con la funzione \funcd{closedir}, il cui prototipo è: + stream}, ed il file descriptor ad esso associato, con la funzione +\funcd{closedir}, il cui prototipo è: \begin{functions} \headdecl{sys/types.h} \headdecl{dirent.h} @@ -1042,11 +1082,12 @@ 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 è +A parte queste funzioni di base in BSD 4.3 venne 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 - \acr{libc4}.} ed il suo prototipo è: + \acr{libc4} e richiede siano definite le macro \macro{\_BSD\_SOURCE} o + \macro{\_SVID\_SOURCE}.} ed il suo prototipo è: \begin{prototype}{dirent.h}{int scandir(const char *dir, struct dirent ***namelist, int(*filter)(const struct dirent *), int(*compar)(const struct dirent **, const struct dirent **))} @@ -1114,13 +1155,6 @@ estensione\footnote{le glibc, a partire dalla versione 2.1, effettuano anche ordina i nomi tenendo conto del numero di versione (cioè qualcosa per cui \texttt{file10} viene comunque dopo \texttt{file4}.) -Un semplice esempio dell'uso di queste funzioni è riportato in -fig.~\ref{fig:file_my_ls}, dove si è riportata la sezione principale di un -programma che, usando la funzione di scansione illustrata in -fig.~\ref{fig:file_dirscan}, stampa i nomi dei file contenuti in una directory -e la relativa dimensione (in sostanza una versione semplificata del comando -\cmd{ls}). - \begin{figure}[!htb] \footnotesize \centering \begin{minipage}[c]{15.6cm} @@ -1131,26 +1165,33 @@ e la relativa dimensione (in sostanza una versione semplificata del comando \label{fig:file_my_ls} \end{figure} +Un semplice esempio dell'uso di queste funzioni è riportato in +fig.~\ref{fig:file_my_ls}, dove si è riportata la sezione principale di un +programma che, usando la funzione di scansione illustrata in +fig.~\ref{fig:file_dirscan}, stampa i nomi dei file contenuti in una directory +e la relativa dimensione (in sostanza una versione semplificata del comando +\cmd{ls}). + Il programma è estremamente semplice; in fig.~\ref{fig:file_my_ls} si è omessa la parte di gestione delle opzioni (che prevede solo l'uso di una funzione per la stampa della sintassi, anch'essa omessa) ma il codice completo potrà essere trovato coi sorgenti allegati nel file \file{myls.c}. In sostanza tutto quello che fa il programma, dopo aver controllato -(\texttt{\small 10--13}) di avere almeno un argomento (che indicherà la -directory da esaminare) è chiamare (\texttt{\small 14}) la funzione +(\texttt{\small 12--15}) di avere almeno un argomento (che indicherà la +directory da esaminare) è chiamare (\texttt{\small 16}) la funzione \func{DirScan} per eseguire la scansione, usando la funzione \code{do\_ls} -(\texttt{\small 20--26}) per fare tutto il lavoro. +(\texttt{\small 22--29}) per fare tutto il lavoro. -Quest'ultima si limita (\texttt{\small 23}) a chiamare \func{stat} sul file +Quest'ultima si limita (\texttt{\small 26}) a chiamare \func{stat} sul file indicato dalla directory entry passata come argomento (il cui nome è appunto \var{direntry->d\_name}), memorizzando in una opportuna struttura \var{data} i -dati ad esso relativi, per poi provvedere (\texttt{\small 24}) a stampare il -nome del file e la dimensione riportata in \var{data}. +dati ad esso relativi, per poi provvedere (\texttt{\small 27}) a stampare il +nome del file e la dimensione riportata in \var{data}. Dato che la funzione verrà chiamata all'interno di \func{DirScan} per ogni voce presente questo è sufficiente a stampare la lista completa dei file e -delle relative dimensioni. Si noti infine come si restituisca sempre 0 come +delle relative dimensioni. Si noti infine come si restituisca sempre 0 come valore di ritorno per indicare una esecuzione senza errori. \begin{figure}[!htb] @@ -1166,17 +1207,17 @@ valore di ritorno per indicare una esecuzione senza errori. Tutto il grosso del lavoro è svolto dalla funzione \func{DirScan}, riportata in fig.~\ref{fig:file_dirscan}. La funzione è volutamente generica e permette di eseguire una funzione, passata come secondo argomento, su tutte le voci di -una directory. La funzione inizia con l'aprire (\texttt{\small 19--23}) uno +una directory. La funzione inizia con l'aprire (\texttt{\small 18--22}) uno stream sulla directory passata come primo argomento, stampando un messaggio in caso di errore. -Il passo successivo (\texttt{\small 24--25}) è cambiare directory di lavoro -(vedi sez.~\ref{sec:file_work_dir}), usando in sequenza le funzione +Il passo successivo (\texttt{\small 23--24}) è cambiare directory di lavoro +(vedi sez.~\ref{sec:file_work_dir}), usando in sequenza le funzioni \func{dirfd} e \func{fchdir} (in realtà si sarebbe potuto usare direttamente \func{chdir} su \var{dirname}), in modo che durante il successivo ciclo -(\texttt{\small 27--31}) sulle singole voci dello stream ci si trovi +(\texttt{\small 26--30}) sulle singole voci dello stream ci si trovi all'interno della directory.\footnote{questo è essenziale al funzionamento - della funzione \code{do\_ls} (e ad ogni funzione che debba usare il campo + della funzione \code{do\_ls}, e ad ogni funzione che debba usare il campo \var{d\_name}, in quanto i nomi dei file memorizzati all'interno di una struttura \struct{dirent} sono sempre relativi alla directory in questione, e senza questo posizionamento non si sarebbe potuto usare \func{stat} per @@ -1184,20 +1225,20 @@ all'interno della directory.\footnote{questo è essenziale al funzionamento Avendo usato lo stratagemma di fare eseguire tutte le manipolazioni necessarie alla funzione passata come secondo argomento, il ciclo di scansione della -directory è molto semplice; si legge una voce alla volta (\texttt{\small 27}) +directory è molto semplice; si legge una voce alla volta (\texttt{\small 26}) all'interno di una istruzione di \code{while} e fintanto che si riceve una -voce valida (cioè un puntatore diverso da \val{NULL}) si esegue +voce valida, cioè un puntatore diverso da \val{NULL}, si esegue (\texttt{\small 27}) la funzione di elaborazione \var{compare} (che nel nostro caso sarà \code{do\_ls}), ritornando con un codice di errore (\texttt{\small - 28}) qualora questa presenti una anomalia (identificata da un codice di -ritorno negativo). Una volta terminato il ciclo la funzione si conclude con la + 28}) qualora questa presenti una anomalia, identificata da un codice di +ritorno negativo. Una volta terminato il ciclo la funzione si conclude con la chiusura (\texttt{\small 32}) dello stream\footnote{nel nostro caso, uscendo subito dopo la chiamata, questo non servirebbe, in generale però l'operazione è necessaria, dato che la funzione può essere invocata molte volte all'interno dello stesso processo, per cui non chiudere i \textit{directory stream} comporterebbe un consumo progressivo di risorse, con conseguente rischio di esaurimento delle stesse.} e la restituzione -(\texttt{\small 33}) del codice di operazioni concluse con successo. +(\texttt{\small 32}) del codice di operazioni concluse con successo. \subsection{La directory di lavoro} @@ -4967,14 +5008,14 @@ programmi e librerie) di cui il server potrebbe avere bisogno. % LocalWords: gid Control List patch mandatory control execute group other all % LocalWords: dell' effective passwd IGID locking swap saved text IRWXU IRWXG % LocalWords: IRWXO ext reiser capability FSETID mask capabilities chroot jail -% LocalWords: FTP Di filter reiserfs Attributes Solaris Posix FreeBSD libacl +% LocalWords: FTP Di filter reiserfs Attributes Solaris FreeBSD libacl hash % LocalWords: XFS SELinux namespace attribute security trusted Draft Modules % LocalWords: attributes mime ADMIN FOWNER libattr lattr getxattr lgetxattr of % LocalWords: fgetxattr attr ssize ENOATTR ENOTSUP NUL setxattr lsetxattr list % LocalWords: fsetxattr flags XATTR REPLACE listxattr llistxattr flistxattr by % LocalWords: removexattr lremovexattr fremovexattr attributename lacl acl tv % LocalWords: OBJ setfacl len any prefix separator options NUMERIC IDS SMART -% LocalWords: INDENT major number IDE Documentation makedev fopendir proc copy +% LocalWords: INDENT major number IDE Documentation makedev proc copy % LocalWords: euidaccess eaccess delete def tag qualifier permset calendar NOW % LocalWords: mutt noatime relatime strictatime atim nsec mtim ctim atimensec % LocalWords: mtimensec utimes timeval futimes lutimes ENOSYS futimens OMIT @@ -4988,7 +5029,7 @@ programmi e librerie) di cui il server potrebbe avere bisogno. % LocalWords: bounding execve fork capget capset header hdrp datap ESRCH undef % LocalWords: version libcap lcap clear ncap caps pag capgetp CapInh CapPrm % LocalWords: fffffeff CapEff getcap dell'IPC scheduling dell'I lookup dcookie -% LocalWords: NEWNS unshare nice NUMA ioctl journaling +% LocalWords: NEWNS unshare nice NUMA ioctl journaling close XOPEN fdopendir %%% Local Variables: %%% mode: latex diff --git a/fileunix.tex b/fileunix.tex index aa4b86a..9a3eb6f 100644 --- a/fileunix.tex +++ b/fileunix.tex @@ -1143,15 +1143,15 @@ molti casi in cui sarebbe invece utile che ogni singolo \itindex{thread} Per risolvere questi problemi, riprendendo una interfaccia già presente in Solaris, a fianco delle normali funzioni che operano sui file (come \func{open}, \func{mkdir}, ecc.) sono state introdotte delle ulteriori -funzioni, contraddistinte dal suffisso \texttt{at}, che permettono l'apertura -di un file (o le rispettive altre operazioni) usando un pathname relativo ad -una directory specificata.\footnote{l'introduzione è avvenuta su proposta - dello sviluppatore principale delle \acr{glibc} Urlich Drepper; le - corrispondenti system call sono state inserite nel kernel ufficiale a - partire dalla versione 2.6.16, in precedenza era disponibile una emulazione - che, sia pure con prestazioni inferiori, funzionava facendo ricorso all'uso - del filesystem \textit{proc} con l'apertura del file attraverso il - riferimento a pathname del tipo di +funzioni, dette anche funzioni ``\textit{at}'' in quanto contraddistinte dal +suffisso \texttt{at}, che permettono l'apertura di un file (o le rispettive +altre operazioni) usando un pathname relativo ad una directory +specificata.\footnote{l'introduzione è avvenuta su proposta dello sviluppatore + principale delle \acr{glibc} Urlich Drepper; le corrispondenti system call + sono state inserite nel kernel ufficiale a partire dalla versione 2.6.16, in + precedenza era disponibile una emulazione che, sia pure con prestazioni + inferiori, funzionava facendo ricorso all'uso del filesystem \textit{proc} + con l'apertura del file attraverso il riferimento a pathname del tipo di \texttt{/proc/self/fd/dirfd/relative\_path}.} Benché queste funzioni non siano presenti negli standard tradizionali esse sono state adottate da vari Unix\footnote{oltre a Linux e Solaris sono presenti in vari BSD.} fino ad diff --git a/intro.tex b/intro.tex index b481353..ae6fa9c 100644 --- a/intro.tex +++ b/intro.tex @@ -258,7 +258,7 @@ libreria e quello di una chiamata al sistema. Le librerie standard del C consentono comunque, nel caso non sia presente una specifica funzione di libreria corrispondente, di eseguire una \textit{system call} generica tramite la funzione \funcd{syscall}, il cui prototipo, -accessible se si è definita la macro \macro{\_GNU\_SOURCE}, (vedi +accessibile se si è definita la macro \macro{\_GNU\_SOURCE}, (vedi sez.~\ref{sec:intro_gcc_glibc_std}) è: \begin{functions} \headdecl{unistd.h} @@ -837,6 +837,9 @@ in esse definite, sono illustrate nel seguente elenco: \item a partire dalla versione 2.3.3 delle \acr{glibc} un valore maggiore o uguale a ``\texttt{200112L}'' rende disponibili le funzionalità di base previste dallo standard POSIX.1-2001, escludendo le estensioni XSI; + \item a partire dalla versione 2.10 delle \acr{glibc} un valore maggiore o + uguale a ``\texttt{200809L}'' rende disponibili le funzionalità di base + previste dallo standard POSIX.1-2008, escludendo le estensioni XSI; \item in futuro valori superiori potranno abilitare ulteriori estensioni. \end{itemize} @@ -885,6 +888,10 @@ in esse definite, sono illustrate nel seguente elenco: ``\texttt{600}'' o superiore rende disponibili anche le funzionalità introdotte con SUSv3, corrispondenti allo standard POSIX.1-2001 più le estensioni XSI. + \item a partire dalla versione 2.10 delle \acr{glibc} un valore uguale a + ``\texttt{700}'' o superiore rende disponibili anche le funzionalità + introdotte con SUSv4, corrispondenti allo standard POSIX.1-2008 più le + estensioni XSI. \end{itemize} \item[\macro{\_XOPEN\_SOURCE\_EXTENDED}] definendo questa macro si rendono @@ -958,10 +965,10 @@ una opportuna macro; queste estensioni sono illustrate nel seguente elenco: estensione ad uso di transizione per le \textit{Single UNIX Specification}, per consentire la gestione di file di grandi dimensioni anche nei sistemi a 32 bit, in cui la dimensione massima, espressa con un intero, non poteva - superare i 2 gigabyte. Nei nuovi programmi queste funzioni devono essere - evitate, a favore dell'uso macro \macro{\_FILE\_OFFSET\_BITS}, che definita - al valore di \texttt{64} consente di usare in maniera trasparente le - funzioni dell'interfaccia classica. + superare i 2Gb. Nei nuovi programmi queste funzioni devono essere evitate, + a favore dell'uso macro \macro{\_FILE\_OFFSET\_BITS}, che definita al valore + di \texttt{64} consente di usare in maniera trasparente le funzioni + dell'interfaccia classica. \item[\macro{\_FILE\_OFFSET\_BITS}] la definizione di questa macro al valore di \texttt{64} consente di attivare la conversione automatica di tutti i @@ -1013,16 +1020,22 @@ una opportuna macro; queste estensioni sono illustrate nel seguente elenco: di base che non cambiano il comportamento dei programmi se si richiede una ottimizzazione di livello uno o superiore,\footnote{vale a dire se si usa l'opzione \texttt{-O1} o superiore del \texttt{gcc}.} mentre con il - valore \texttt{2} vengono aggiunti maggiori controlli. + valore \texttt{2} vengono aggiunti maggiori controlli. Dato che alcuni dei + controlli vengono effettuati in fase di compilazione l'uso di questa macro + richiede anche la collaborazione del compilatore, disponibile dalla + versione 4.0 del \texttt{gcc}. \end{basedescript} Se non è stata specificata esplicitamente nessuna di queste macro il default assunto è che siano definite \macro{\_BSD\_SOURCE}, \macro{\_SVID\_SOURCE}, -\macro{\_POSIX\_SOURCE}, e \macro{\_POSIX\_C\_SOURCE} con valore -``\texttt{200112L}'' (o ``\texttt{199506L}'' per le versioni delle \acr{glibc} -precedenti la 2.4). Si ricordi infine che perché queste macro abbiano effetto -devono essere sempre definite prima dell'inclusione dei file di dichiarazione. +\macro{\_POSIX\_SOURCE} e, con le \acr{glibc} più recenti, che la macro +\macro{\_POSIX\_C\_SOURCE} abbia il valore ``\texttt{200809L}'', per versioni +precedenti delle \acr{glibc} il valore assegnato a \macro{\_POSIX\_C\_SOURCE} +era di ``\texttt{200112L}'' prima delle 2.10, di ``\texttt{199506L}'' prima +delle 2.4, di ``\texttt{199506L}'' prima delle 2.1. Si ricordi infine che +perché queste macro abbiano effetto devono essere sempre definite prima +dell'inclusione dei file di dichiarazione. % vedi anche man feature_test_macros @@ -1048,9 +1061,10 @@ devono essere sempre definite prima dell'inclusione dei file di dichiarazione. % LocalWords: Technical TC SUS Opengroup features STRICT std ATFILE fseeko % LocalWords: ftello fseek ftell lseek FORTIFY REENTRANT SAFE overflow memcpy % LocalWords: mempcpy memmove memset stpcpy strcpy strncpy strcat strncat gets -% LocalWords: sprintf snprintf vsprintf vsnprintf +% LocalWords: sprintf snprintf vsprintf vsnprintf syscall number calendar BITS %%% Local Variables: %%% mode: latex %%% TeX-master: "gapil" %%% End: +% LocalWords: pathname diff --git a/listati/dirent.c b/listati/dirent.c index f8e4c25..23abffe 100644 --- a/listati/dirent.c +++ b/listati/dirent.c @@ -2,6 +2,7 @@ struct dirent { 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 */ - char d_name[256]; /* We must not include limits.h! */ + unsigned char d_type; /* type of file; + by all file system types */ + char d_name[256]; /* filename */ }; diff --git a/listati/my_ls.c b/listati/my_ls.c index 1ff634a..ce97f2d 100644 --- a/listati/my_ls.c +++ b/listati/my_ls.c @@ -3,7 +3,6 @@ #include /* directory */ #include /* C standard library */ #include - /* computation function for DirScan */ int do_ls(struct dirent * direntry); /* main body */ @@ -24,7 +23,7 @@ int do_ls(struct dirent * direntry) { struct stat data; - stat(direntry->d_name, &data); /* get stat data */ + stat(direntry->d_name, &data); /* get stat data */ printf("File: %s \t size: %d\n", direntry->d_name, data.st_size); return 0; } -- 2.30.2