X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=blobdiff_plain;f=filedir.tex;h=0d6dbdba57a2fb2fe0e10d76745a240af656a4ee;hp=361e05a5afbcf9fffca3288cefe625b79ed41e48;hb=34ed932cc43ebd3df23ce3255984bba0301b7231;hpb=a88d4dd8fdd85cdfe8fd04684d4afb4c24174995 diff --git a/filedir.tex b/filedir.tex index 361e05a..0d6dbdb 100644 --- a/filedir.tex +++ b/filedir.tex @@ -13,7 +13,7 @@ dei file Le prime funzioni che considereremo sono quelle relative alla gestione di file e directory, secondo le caratteristiche standard che essi presentano in un -filesystem unix, già esaminate in precedenza (vedi +filesystem unix, la cui struttura abbiamo esaminato in precedenza (vedi \secref{sec:fileintr_filesystem}). \subsection{Le funzioni \texttt{link} e \texttt{unlink}} @@ -89,14 +89,14 @@ filesystem; inoltre il filesystem deve supportare i collegamenti diretti (non il caso ad esempio del filesystem \texttt{vfat} di windows). La funzione opera sui file ordinari, come sugli altri oggetti del filesystem, -ma solo l'amministratore è in grado di creare un collegamento diretto ad -un'altra directory, questo lo si fa perché in questo caso è possibile creare -dei circoli nel filesystem (vedi \secref{sec:fileintr_symlink}) che molti -programmi non sono in grado di gestire e la cui rimozione diventa estremamente -complicata (in genere occorre far girare il programma \texttt{fsck} per -riparare il filesystem); data la sua pericolosità in Linux questa -caratteristica è stata disabilitata, e la funzione restituisce l'errore -\texttt{EPERM}. +in alcuni filesystem solo l'amministratore è in grado di creare un +collegamento diretto ad un'altra directory, questo lo si fa perché in questo +caso è possibile creare dei circoli nel filesystem (vedi +\secref{sec:fileintr_symlink}) che molti programmi non sono in grado di +gestire e la cui rimozione diventa estremamente complicata (in genere occorre +far girare il programma \texttt{fsck} per riparare il filesystem); data la sua +pericolosità in generale nei filesystem usati in Linux questa caratteristica è +stata disabilitata, e la funzione restituisce l'errore \texttt{EPERM}. La rimozione di un file (o più precisamente della voce che lo referenzia) si effettua con la funzione \texttt{unlink}; il suo prototipo è il seguente: @@ -255,10 +255,10 @@ al kernel (analogamente a quanto avviene per le directory) per cui la chiamata ad una \texttt{open} o una \texttt{stat} su un link simbolico comporta la lettura del contenuto del medesimo e l'applicazione della funzione al file specificato da quest'ultimo. Invece altre funzioni come quelle per cancellare -o rinominare i file operano direttamente sul link simbolico. Inoltre esistono -funzioni apposite, come la \texttt{readlink} e la \texttt{lstat} per accedere -alle informazioni del link invece che a quelle del file a cui esso fa -riferimento. +o rinominare i file operano direttamente sul link simbolico (per l'elenco vedi +\ntab). Inoltre esistono funzioni apposite, come la \texttt{readlink} e la +\texttt{lstat} per accedere alle informazioni del link invece che a quelle del +file a cui esso fa riferimento. Le funzioni per operare sui link simbolici sono le seguenti, esse sono tutte dichiarate nell'header file \texttt{unistd.h}. @@ -310,8 +310,86 @@ questa funzione \end{errlist} \end{prototype} -\section{La manipolazione delle directories} -\label{sec:filedir_dir_handling} +In \ntab\ si è riportato un elenco dei comportamenti delle varie funzioni che +operano sui file rispetto ai link simbolici; specificando quali seguono il +link simbolico e quali possono operare direttamente sul suo contenuto. +\begin{table}[htb] + \centering + \footnotesize + \begin{tabular}[c]{|l|c|c|} + \hline + Funzione & Segue il link & Non segue il link \\ + \hline + \hline + \func{access} & $\bullet$ & \\ + \func{chdir} & $\bullet$ & \\ + \func{chmod} & $\bullet$ & \\ + \func{chown} & & $\bullet$ \\ + \func{creat} & $\bullet$ & \\ + \func{exec} & $\bullet$ & \\ + \func{lchown} & $\bullet$ & $\bullet$ \\ + \func{link} & & \\ + \func{lstat} & & $\bullet$ \\ + \func{mkdir} & $\bullet$ & \\ + \func{mkfifo} & $\bullet$ & \\ + \func{mknod} & $\bullet$ & \\ + \func{open} & $\bullet$ & \\ + \func{opendir} & $\bullet$ & \\ + \func{pathconf} & $\bullet$ & \\ + \func{readlink} & & $\bullet$ \\ + \func{remove} & & $\bullet$ \\ + \func{rename} & & $\bullet$ \\ + \func{stat} & $\bullet$ & \\ + \func{truncate} & $\bullet$ & \\ + \func{unlink} & & $\bullet$ \\ + \hline + \end{tabular} + \caption{Uso dei link simbolici da parte di alcune funzioni.} + \label{tab:filedir_symb_effect} +\end{table} +si noti che non si è specificato il comportamento delle funzioni che operano +con i file descriptor, in quanto la gestione del link simbolico viene in +genere effttuata dalla funzione che restituisce il file descriptor +(normalmente la \func{open}). + +\begin{figure}[htb] + \centering + \includegraphics[width=5cm]{img/link_loop.eps} + \caption{Esempio di loop nel filesystem creato con un link simbolico.} + \label{fig:filedir_link_loop} +\end{figure} + +Un caso comune che si può avere con i link simbolici è la creazione dei +cosiddetti \textit{loop}. La situazione è illustrata in \curfig, 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 estremamente avanzato in grado di accedere direttamente + attraverso vari filesystem al file da lanciare come sistema operativo) di + vedere i file in questa directory, che è montata su una partizione separata + (e che grub vedrebbe come radice), con lo stesso path con cui verrebbero + visti dal sistema operativo.}. + +Questo può causare problemi per tutti quei programmi che effettuassero uno +scan di una directory senza tener conto dei link simbolici, in quel caso +infatti il loop nella directory + +Un secondo punto da tenere presente è che un link simbolico può essere fatto +anche ad un file che non esiste; ad esempio possiamo creare un file temporaneo +nella nostra directory con un link del tipo: +\begin{verbatim} +$ln -s /tmp/tmp_file temporaneo +\end{verbatim}%$ +ma anche se \file{/tmp/tmp_file} non esiste. Aprendo in scrittura +\file{temporaneo} questo verrà scritto; ma se cercassimo di accederlo in sola +lettura (ad esempio con \cmd{cat}) otterremmo: +\begin{verbatim} +$ cat prova +cat: prova: No such file or directory +\end{verbatim}%$ +con un errore che sembra sbagliato, dato \cmd{ls} ci mostrerebbe l'esistenza +di \file{temporaneo}. + \subsection{Le funzioni \texttt{mkdir} e \texttt{rmdir}} \label{sec:filedir_dir_creat_rem} @@ -435,7 +513,7 @@ per cambiare directory di lavoro. \begin{prototype}{unistd.h}{int fchdir (int filedes)} Analoga alla precedente, ma usa un file descriptor invece del pathname. - + Entrambe le funzioni restituiscono zero in caso di successo e -1 per un errore, in caso di errore \texttt{errno} viene settata secondo i codici di errore standard di accesso ai files (trattati in dettaglio in @@ -461,7 +539,7 @@ manipolazione sar \label{sec:filedir_stat} La lettura delle informazioni relative ai file è fatta attraverso la famiglia -delle funzioni \texttt{stat}, che è la funzione che il comando \texttt{ls} usa +delle funzioni \func{stat}, che è la funzione che il comando \cmd{ls} usa per poter stampare tutti i dati dei files. I prototipi di queste funzioni sono i seguenti: \begin{functions} @@ -475,31 +553,31 @@ i seguenti: \funcdecl{int lstat(const char *file\_name, struct stat *buf)} Identica a \func{stat} eccetto che se il \var{file\_name} è un link simbolico vengono - lette le informazioni relativa ad esso e non al file a cui punta. + lette le informazioni relativa ad esso e non al file a cui fa riferimento. \funcdecl{int fstat(int filedes, struct stat *buf)} Identica a \func{stat} - eccetto che funziona con un file aperto, specificato tramite il suo file + eccetto che si usa con un file aperto, specificato tramite il suo file descriptor \var{filedes}. Le funzioni restituiscono zero in caso di successo e -1 per un errore, in caso di errore \texttt{errno} viene settato ai valori: \begin{errlist} - \item \texttt{EACCESS} Non c'è il permesso di accedere al file. - \item \texttt{ENOTDIR} Una componente del pathname non è una directory. - \item \texttt{EMLOOP} Ci sono troppi link simbolici nel pathname. - \item \texttt{EFAULT} I puntatori usati sono fuori dallo spazio di indirizzi + \item \texttt{EACCESS} non c'è il permesso di accedere al file. + \item \texttt{ENOTDIR} una componente del pathname non è una directory. + \item \texttt{EMLOOP} ci sono troppi link simbolici nel pathname. + \item \texttt{EFAULT} i puntatori usati sono fuori dallo spazio di indirizzi del processo. \item \texttt{ENOMEM} il kernel non ha a disposizione memoria sufficiente a completare l'operazione. - \item \texttt{ENAMETOOLONG} Il filename è troppo lungo. + \item \texttt{ENAMETOOLONG} il filename è troppo lungo. \end{errlist} \end{functions} La struttura \texttt{stat} è definita nell'header \texttt{sys/stat.h} e in generale dipende dall'implementazione, la versione usata da Linux è mostrata in \nfig, così come riportata dalla man page (in realtà la definizione -effettivamente usata nel kernel dipende dall'archietettura e ha altri campi -riservati per estensioni come tempo più precisi, o per il padding dei campi). +effettivamente usata nel kernel dipende dall'architettura e ha altri campi +riservati per estensioni come tempi più precisi, o per il padding dei campi). \begin{figure}[!htb] \footnotesize @@ -567,8 +645,9 @@ simbolici e socket definite da BDS, l'elenco \end{table} Oltre a queste macro è possibile usare direttamente il valore di -\var{st\_mode} per ricavare il significato dei vari bit del campo attraverso -l'uso dei flag riportati in \ntab: +\var{st\_mode} per ricavare il significato dei vari bit in esso memorizzati, +per questo sempre in \texttt{sys/stat.h} sono definiti i flag riportati in +\ntab: \begin{table}[htb] \centering \footnotesize @@ -608,14 +687,118 @@ l'uso dei flag riportati in \ntab: \label{tab:filedir_file_mode_flags} \end{table} +Il primo valore definisce la maschera dei bit usati nei quali viene +memorizzato il tipo di files, mentre gli altri possono essere usati per +effettuare delle selezioni sul tipo di file voluto, combinando opportunamente +i vari flag; ad esempio se si volesse controllare se un file è una directory o +un file ordinario si potrebbe definire la condizione: +\begin{lstlisting} +#define IS_FILE_DIR(x) ( ((x) & S_IFMT) & (S_IFDIR | S_IFREG) ) +\end{lstlisting} +in cui prima si estraggono da \var{st\_mode} i bit relativi al tipo di file e +poi si effettua il confronto con la combinazione di tipi scelta. + \subsection{La dimensione dei file} \label{sec:filedir_file_size} -Il membro \var{st\_size} contiene la dimensione del +Il membro \var{st\_size} contiene la dimensione del file in bytes (se il file +è un file normale, nel caso di un link simbolico al dimensione è quella del +pathname che contiene). + +Il campo \var{st\_blocks} definisce la lunghezza del file in blocchi di 512 +bytes. Il campo \var{st\_blksize} infine definisce la dimensione preferita per +i trasferimenti sui file (che è la dimensione usata anche dalle librerie del C +per l'interfaccia degli stream); scrivere sul file a blocchi di dati di +dimensione inferiore sarebbe inefficiente. + +Si tenga conto che lunghezza del file riportata in \var{st\_size} non è detto +che corrisponda all'occupazione dello spazio su disco per via della possibile +esistenza dei cosiddetti \textsl{buchi} (detti normalmente \textit{holes}) che +si formano tutte le volte che si va a scrivere su un file dopo aver eseguito +una \func{seek} (vedi \secref{sec:fileunix_lseek}) oltre la sua conclusione +corrente. + +In tal caso si avranno differenti risultati a seconda del modi in cui si +calcola la lunghezza del file, ad esempio il comando \cmd{du}, (che riporta il +numero di blocchi occupati) potrà dare una dimensione inferiore, mentre se si +legge dal file (ad esempio usando \cmd{wc -c}), dato che in tal caso per le +parti non scritte vengono restituiti degli zeri, si avrà lo stesso risultato +di \cmd{ls}. + +Se è sempre possibile allargare un file scrivendoci sopra od usando la +funzione \func{seek} per spostarsi oltre la sua fine. Esistono però anche casi +in cui si può avere bisogno di effettuare un troncamento scartando i dati al +di là della dimensione scelta come nuova fine del file. + +Un file può essere troncato a zero aprendolo con il flag \macro{O\_TRUNC}, ma +questo è un caso particolare; per qualunque altra dimensione si possono usare +le due funzioni: +\begin{functions} + \headdecl{unistd.h} \funcdecl{int truncate(const char *file\_name, off\_t + length)} Fa si che la dimensione del file \var{file\_name} sia troncata ad + un valore massimo specificato da \var{lenght}. + + \funcdecl{int ftruncate(int fd, off\_t length))} Identica a \func{truncate} + eccetto che si usa con un file aperto, specificato tramite il suo file + descriptor \var{fd}, + + Le funzioni restituiscono zero in caso di successo e -1 per un errore, in + caso di errore \texttt{errno} viene settato ai valori: + \begin{errlist} + \item \texttt{EACCESS} non c'è il permesso di accedere al file. + \item \texttt{ENOTDIR} una componente del pathname non è una directory. + \item \texttt{EMLOOP} ci sono troppi link simbolici nel pathname. + \item \texttt{EFAULT} i puntatori usati sono fuori dallo spazio di indirizzi + del processo. + \item \texttt{ENOMEM} il kernel non ha a disposizione memoria sufficiente a + completare l'operazione. + \item \texttt{ENOENT} il file non esiste. + \item \texttt{ENAMETOOLONG} il filename è troppo lungo. + \end{errlist} +\end{functions} + +Se il file è più lungo della lunghezza specificata i dati in eccesso saranno +perduti; il comportamento in caso di lunghezza inferiore non è specificato e +dipende dall'implementazione: il file può essere lasciato invariato o esteso +fino alla lunghezza scelta; in quest'ultimo caso lo spazio viene riempito con +zeri (e in genere si ha la creazione di un hole nel file). \subsection{I tempi dei file} \label{sec:filedir_file_times} +Il sistema mantiene per ciascun file tre tempi. Questi sono registrati +nell'inode insieme agli altri attibuti del file e possono essere letti tramite +la funzione \func{stat}, che li restituisce attraverso tre campi della +struttura in \figref{fig:filedir_stat_struct} il cui signifato è riportato +nello schema in \ntab: + +\begin{table}[htb] + \centering + \begin{tabular}[c]{|c|l|l|c|} + \var{st\_atime}& ultimo accesso ai dati del file &\func{read}& \cmd{-u}\\ + \var{st\_mtime}& ultima modifica ai dati del file &\func{write}& default\\ + \var{st\_ctime}& ultima modifica ai dati dell'inode&\func{chmod}, + \func{utime} & \cmd{-c} \\ + \end{tabular} + \caption{I tre tempi associati a ciascun file} + \label{tab:filedir_file_times} +\end{table} + + +La differenza principale di cui tenere presente è quella fra tempo di modifica +\var{st\_mtime} e tempo di cambiamento di stato \var{st\_ctime}. Il primo +infatti fa riferimento ad una modifica del contenuto di un file, mentre il +secondo ad una modifica dell'inode; siccome esistono molte operazioni (come la +funzione \func{link} e molte altre che vedremo in seguito) che modificano solo +le informazioni contenute nell'inode senza toccare il file, dato che queste +ultime sono separate dal contenuto del file diventa necessario l'utilizzo di +un altro tempo. Si noti inoltre come \var{st\_ctime} non abbia nulla a che +fare con il tempo di creazione usato da molti altri sistemi operativi, che in +unix non esiste. + + + + \subsection{La funzione \texttt{utime}} \label{sec:filedir_utime} @@ -672,6 +855,11 @@ pertanto accesso senza restrizione a qualunque file del sistema. \subsection{I flag \texttt{suid} e \texttt{sgid}} \label{sec:filedir_suid_sgid} + + + + + \subsection{La titolarità di nuovi files e directory} \label{sec:filedir_ownership}