X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=blobdiff_plain;f=filedir.tex;h=db127ae9f548fb956646cdd02899dab01b1dc085;hp=db9c352402dc45ab9846afe37bd79ca9fa471008;hb=ffde006b4b38517dd190c394b769c619d13174a5;hpb=dc5d6dd815d1aeac2f42891ec2f0a3f38c816ac1 diff --git a/filedir.tex b/filedir.tex index db9c352..db127ae 100644 --- a/filedir.tex +++ b/filedir.tex @@ -1,4 +1,4 @@ -\chapter{Files e directories} +\chapter{File e directory} \label{cha:files_and_dirs} In questo capitolo tratteremo in dettaglio le modalità con cui si gestiscono @@ -11,7 +11,7 @@ capitoli successivi. \section{Il controllo di accesso ai file} -\label{sec:filedir_access_control} +\label{sec:file_access_control} Una delle caratteristiche fondamentali di tutti i sistemi unix-like è quella del controllo di accesso ai file, che viene implementato per qualunque @@ -20,51 +20,52 @@ le funzioni usate per gestirne i vari aspetti. \subsection{I permessi per l'accesso ai file} -\label{sec:filedir_perm_overview} +\label{sec:file_perm_overview} Il controllo di accesso ai file in unix segue un modello abbastanza semplice, ma adatto alla gran parte delle esigenze, in cui si dividono i permessi su tre livelli. Si tenga conto poi che quanto diremo è vero solo per filesystem di tipo unix, e non è detto che sia applicabile a un filesystem qualunque\footnote{ed infatti non è vero per il filesystem vfat di Windows, - per il quale vengono assegnati in maniera fissa con un opzione in fase di - montaggio}. Esistono inoltre estensioni che permettono di implementare le -ACL (\textit{Access Control List}) che sono un meccanismo di controllo di -accesso molto più sofisticato. + per il quale i permessi vengono assegnati in maniera fissa con un opzione in + fase di montaggio}. Esistono inoltre estensioni che permettono di +implementare le ACL (\textit{Access Control List}) che sono un meccanismo di +controllo di accesso molto più sofisticato. Ad ogni file unix associa sempre l'utente che ne è proprietario (il cosiddetto \textit{owner}) e il gruppo di appartenenza, secondo il meccanismo degli -identificatori di utenti e gruppi (\textsl{uid} e \textsl{gid}), e accessibili -da programm tramite i campi \var{st\_uid} e \var{st\_gid} della struttura -\var{stat} (si veda \secref{sec:filedir_stat}). Ad ogni file viene inoltre -associato un insieme di permessi che sono divisi in tre classi, e cioè -attribuiti rispettivamente all'utente proprietario del file, a un qualunque -utente faccia parte del gruppo cui appartiene il file, e a tutti gli altri -utenti. - -I permessi sono espressi da un insieme di 12 bit: di questi i nove meno -significativi sono usati a gruppi di tre per indicare i permessi base di -lettura, scrittura ed esecuzione (indicati rispettivamente con le lettere -\textsl{w}, \textit{r} \textsl{x} nei comandi di sistema) applicabili -rispettivamente al proprietario, al gruppo, a tutti. I restanti tre bit -(\textsl{suid}, \textsl{sgid}, e \textsl{sticky}) sono usati per indicare -alcune caratteristiche più complesse su cui torneremo in seguito (vedi -\secref{sec:filedir_suid_sgid} e \secref{sec:filedir_sticky}). - -Anche i permessi sono tenuti per ciascun file (di qualunque tipo, quindi anche -per le fifo, i socket e i file di dispositivo) nell'inode, in opportuni bit -del campo \var{st\_mode} della struttura letta da \func{stat} (vedi -\figref{fig:filedir_stat_struct}). - - -In genere ci si riferisce a questi permessi usando le lettere \textsl{u} (per -\textit{user}), \textsl{g} (per \textit{group}) e \textsl{o} (per -\textit{other}), inoltre se si vuole indicare tutti questi gruppi insieme si -usa la lettera \textsl{a} (per \textit{all}). Si tenga ben presente questa -distinzione, dato che in certi casi, mutuando la termimologia in uso nel VMS, -si parla dei permessi base come di permessi di owner, group ed all, le cui -iniziali possono da luogo a confuzione. Le costanti che permettono di accedere -al valore numerico di questi bit sono riportate in \ntab. +identificatori di utenti e gruppi (\textsl{uid} e \textsl{gid}). Questi valori +sono accessibili da programma tramite i campi \var{st\_uid} e \var{st\_gid} +della struttura \var{stat} (si veda \secref{sec:file_stat}). Ad ogni file +viene inoltre associato un insieme di permessi che sono divisi in tre classi, +e cioè attribuiti rispettivamente all'utente proprietario del file, a un +qualunque utente faccia parte del gruppo cui appartiene il file, e a tutti gli +altri utenti. + +I permessi, così come vengono presi dai comandi e dalle routine di sistema, +sono espressi da un numero di 12 bit; di questi i nove meno significativi sono +usati a gruppi di tre per indicare i permessi base di lettura, scrittura ed +esecuzione (indicati nei comandi di sistema con le lettere \cmd{w}, \cmd{r} e +\cmd{x}) ed applicabili rispettivamente al proprietario, al gruppo, a tutti +gli altri. I restanti tre bit (\textsl{suid}, \textsl{sgid}, e +\textsl{sticky}) sono usati per indicare alcune caratteristiche più complesse +su cui torneremo in seguito (vedi \secref{sec:file_suid_sgid} e +\secref{sec:file_sticky}). + +Anche i permessi, come tutte le altre informazioni generali, sono tenuti per +ciascun file nell'inode; in particolare essi sono contenuti in alcuni bit +del campo \var{st\_mode} della struttura letta da \func{stat} (di nuovo si veda +\secref{sec:file_stat} per i dettagli). + +In genere ci si riferisce a questo raggruppamento dei permessi usando le +lettere \cmd{u} (per \textit{user}), \cmd{g} (per \textit{group}) e \cmd{o} +(per \textit{other}), inoltre se si vuole indicare tutti i raggruppamenti +insieme si usa la lettera \cmd{a} (per \textit{all}). Si tenga ben presente +questa distinzione dato che in certi casi, mutuando la terminologia in uso nel +VMS, si parla dei permessi base come di permessi per \textit{owner}, +\textit{group} ed \textit{all}, le cui iniziali possono dar luogo a confusione. +Le costanti che permettono di accedere al valore numerico di questi bit nel +campo \var{st\_mode} sono riportate in \ntab. \begin{table}[htb] \centering @@ -111,23 +112,32 @@ directory (se si hanno i permessi opportuni per il medesimo) ma non si potr vederlo con \cmd{ls} (per crearlo occorrerà anche il permesso di scrittura per la directory). -Il permesso di lettura per un file consente di aprirlo con le opzioni di sola -lettura (\macro{O\_RDONLY}) o di lettura-scrittura (\macro{O\_RDWR}) e -leggerne il contenuto. Il permesso di scrittura consente di aprire un file in -sola scrittura (\macro{O\_WRONLY}) o lettura-scrittura (\macro{O\_RDWR}) e -modificarne il contenuto, lo stesso permesso è necessario per poter troncare -il file con l'opzione \macro{O\_TRUNC}. +Avere il permesso di lettura per un file consente di aprirlo con le opzioni di +sola lettura (\macro{O\_RDONLY}) o di lettura-scrittura (\macro{O\_RDWR}) e +leggerne il contenuto. Avere il permesso di scrittura consente di aprire un +file in sola scrittura (\macro{O\_WRONLY}) o lettura-scrittura +(\macro{O\_RDWR}) e modificarne il contenuto, lo stesso permesso è necessario +per poter troncare il file con l'opzione \macro{O\_TRUNC}. Non si può creare un file fintanto che non si disponga del permesso di esecuzione e di quello di scrittura per la directory di destinazione; gli stessi permessi occorrono per cancellare un file da una directory (si ricordi -che questo non implica necessariamente la rimozione fisica del file), non è -necessario nessun tipo di permesso per il file stesso (infatti esso non viene -toccato, viene solo modificato il contenute della directory). +che questo non implica necessariamente la rimozione del contenuto del file dal +disco), non è necessario nessun tipo di permesso per il file stesso (infatti +esso non viene toccato, viene solo modificato il contenuto della directory, +rimuovendo la voce che ad esso fa rifermento). Per poter eseguire un file (che sia un programma compilato od uno script di -shell), occorre il permesso di esecuzione per il medesimo, inoltre solo i file -regolari possono essere eseguiti. +shell, od un altro tipo di file eseguibile riconosciuto dal kernel), occorre +avere il permesso di esecuzione, inoltre solo i file regolari possono essere +eseguiti. + +I permessi per un link simbolico sono ignorati, contano quelli del file a cui +fa riferimento; per questo in genere \cmd{ls} per un link simbolico riporta +tutti i permessi come concessi; utente e gruppo a cui esso appartiene vengono +ignorati quando il link viene risolto, vengono controllati solo quando viene +richiesta la rimozione del link e quest'ultimo è in una directory con lo +\textsl{sticky bit} settato (si veda \secref{sec:file_sticky}). La procedura con cui il kernel stabilisce se un processo possiede un certo permesso (di lettura, scrittura o esecuzione) si basa sul confronto fra @@ -137,8 +147,8 @@ l'\textit{effective group id} e gli eventuali \textit{supplementary group id} del processo. Per una spiegazione dettagliata degli identificatori associati ai processi si -veda \secref{sec:prochand_perms}; normalmente, a parte quanto vedremo in -\secref{sec:filedir_suid_sgid}, l'\textit{effective user id} e +veda \secref{sec:proc_perms}; normalmente, a parte quanto vedremo in +\secref{sec:file_suid_sgid}, l'\textit{effective user id} e l'\textit{effective group id} corrispondono a uid e gid dell'utente che ha lanciato il processo, mentre i \textit{supplementary group id} sono quelli dei gruppi cui l'utente appartiene. @@ -168,7 +178,7 @@ di accesso sono i seguenti: del file) allora: \begin{itemize} \item se il relativo\footnote{per relativo si intende il bit di user-read se - il processo, vuole accedere in scrittura, quello di user-write per + il processo vuole accedere in scrittura, quello di user-write per l'accesso in scrittura, etc.} bit dei permessi d'accesso dell'utente è settato, l'accesso è consentito \item altrimenti l'accesso è negato @@ -178,7 +188,8 @@ di accesso sono i seguenti: allora: \begin{itemize} \item se il bit dei permessi d'accesso del gruppo è settato, l'accesso è - consentito, altrimenti l'accesso è negato + consentito, + \item altrimenti l'accesso è negato \end{itemize} \item se il bit dei permessi d'accesso per tutti gli altri è settato, l'accesso è consentito, altrimenti l'accesso è negato. @@ -191,63 +202,399 @@ permessi per il gruppo non vengono neanche controllati; lo stesso vale se il processo appartiene ad un gruppo appropriato, in questo caso i permessi per tutti gli altri non vengono controllati. -\subsection{I flag \texttt{suid} e \texttt{sgid}} -\label{sec:filedir_suid_sgid} -Quandi si lancia un programma in genere l'\textit{effective user id} e -l'\textit{effective group id} sono settati rispettivamente all'uid e al gid -dell'utente che ha lanciato il programma. +\subsection{I bit \textsl{suid} e \textsl{sgid}} +\label{sec:file_suid_sgid} + +Come si è accennato (in \secref{sec:file_perm_overview}) nei dodici bit del +campo \var{st\_mode} usati per il controllo di accesso oltre ai bit dei +permessi veri e propri, ci sono altri tre bit che vengono usati per indicare +alcune proprietà speciali dei file. Due di questi sono i bit detti +\textsl{suid} (o \textit{set-user-ID bit}) e \textsl{sgid} (o +\textit{set-group-ID bit}) che sono identificati dalle constanti +\macro{S\_ISUID} e \macro{S\_ISGID}. + +Come spiegato in dettaglio in \secref{sec:proc_exec}, quando si lancia un +programma il comportamendo normale del kernel è quello di settare +l'\textit{effective user id} e l'\textit{effective group id} del nuovo +processo all'uid e al gid del processo corrente, che normalmente corrispondono +dell'utente con cui si è entrati nel sistema. + +Se però il file del programma\footnote{per motivi di sicurezza il kernel + ignora i bit \acr{suid} e \acr{sgid} per gli script eseguibili} (che +ovviamente deve essere eseguibile) ha il bit \acr{suid} settato, il kernel +assegnerà come \textit{effective user id} al nuovo processo l'uid del +proprietario del file al posto dell'uid del processo originario. Avere il bit +\acr{sgid} settato ha lo stesso effetto sull'\textit{effective group id} del +processo. + +I bit \textsl{suid} e \textsl{sgid} vengono usati per permettere agli utenti +normali di usare programmi che abbisognano di privilegi speciali; l'esempio +classico è il comando \cmd{passwd} che ha la necessità di modificare il file +delle password, quest'ultimo ovviamente può essere scritto solo +dall'amministratore, ma non è necessario chiamare l'amministratore per +cambiare la propria password. Infatti il comando \cmd{passwd} appartiene a +root ma ha il bit suid settato per cui quando viene lanciato da un utente +normale parte con i privilegi di root. +Chiaramente avere un processo che ha privilegi superiori a quelli che avrebbe +normalmente l'utente che lo ha lanciato comporta vari rischi, e questo tipo di +programmi devono essere scritti accuratamente per evitare che possano essere +usati per guadagnare privilegi non consentiti (torneremo sull'argomento in +\secref{sec:proc_perms}). + +La presenza dei bit \acr{suid} e \acr{sgid} su un file può essere +rilevata con il comando \cmd{ls -l}, in tal caso comparirà la lettera \cmd{s} +al posto della \cmd{x} in corrispondenza dei permessi di utente o gruppo. La +stessa lettera \cmd{s} può essere usata nel comando \cmd{chmod} per settare +questi bit. Infine questi bit possono essere controllati all'interno di +\var{st\_mode} con l'uso delle due costanti \macro{S\_ISUID} e +\macro{S\_IGID}, i cui valori sono riportati in +\tabref{tab:file_mode_flags}. + +Gli stessi bit vengono ad assumere in significato completamente diverso per le +directory, normalmente infatti Linux usa la convenzione di SVR4 per indicare +con questi bit l'uso della semantica BSD nella creazione di nuovi file (si +veda \secref{sec:file_ownership} per una spiegazione dettagliata al +proposito). + +Infine Linux utilizza il bit \textsl{sgid} per una ulteriore estensione +mutuata da SVR4. Il caso in cui il file abbia il bit \textsl{sgid} settato ma +non il corrispondente bit di esecuzione viene utilizzato per attivare per +quel file il \textit{mandatory locking} (argomento che affronteremo nei +dettagli in \secref{sec:xxx_mandatory_lock}). + + +\subsection{Il bit \textsl{sticky}} +\label{sec:file_sticky} + +L'ultimo dei bit rimanenti, identificato dalla costante \macro{S\_ISVTX}, è in +parte un rimasuglio delle origini dei sistemi unix. A quell'epoca infatti la +memoria virtuale e l'accesso ai files erano molto meno sofisticati e per +ottenere la massima velocità possibile per i programmi usati più comunemente +si poteva settare questo bit. + +L'effetto di questo bit era che il segmento di testo del programma (si veda +\secref{sec:proc_mem_layout} per i dettagli) veniva scritto nella swap la +prima volta che questo veniva lanciato, e vi permaneva fino al riavvio della +mecchina (da questo il nome di \textsl{sticky bit}); essendo la swap un file +continuo indicizzato direttamente in questo modo si poteva risparmiare in +tempo di caricamento rispetto alla ricerca del file su disco. Lo +\textsl{sticky bit} è indicato usando la lettera \cmd{t} al posto della +\cmd{x} nei permessi per gli altri. + +Ovviamente per evitare che gli utenti potessero intasare la swap solo +l'amministratore era in grado di settare questo bit, che venne chiamato anche +con il nome di \textit{saved text bit}, da cui deriva quello della costante. +Le attuali implementazioni di memoria virtuale e filesystem rendono +sostanzialmente inutile questo procedimento. + +Benché ormai non venga più utilizzato per i file, lo \textsl{sticky bit} ha +assunto un uso corrente per le directory\footnote{lo \textsl{sticky bit} per + le directory è una estensione non definita nello standard POSIX, Linux però + la supporta, così come BSD e SVR4}, in questo caso se il bit è settato un +file potrà essere rimosso dalla directory soltanto se l'utente ha il permesso +di scrittura ed inoltre è vera una delle seguenti condizioni: +\begin{itemize} +\item l'utente è proprietario del file +\item l'utente è proprietario della directory +\item l'utente è l'amministratore +\end{itemize} +un classico esempio di directory che ha questo bit settato è \file{/tmp}, i +permessi infatti di solito sono settati come: +\begin{verbatim} +$ ls -ld /tmp +drwxrwxrwt 6 root root 1024 Aug 10 01:03 /tmp +\end{verbatim}%$ +in questo modo chiunque può leggere, scrivere ed eseguire i file temporanei +ivi memorizzati, sia crearne di nuovi, ma solo l'utente che ha creato un file +nella directory potrà cancellarlo o rinominarlo, così si può evitare che un +utente possa, più o meno consapevolemnte, cancellare i file degli altri. -Ma nei dodici bit del campo \var{st\_mode} relativi ai permessi esiste un bit -speciale, il \textit{set-user-ID bit} o suid, che se settato fa si che quando -un programma viene lanciato invece di avere assegnato come \textit{effective - user id} l'uid di chi lo lancia, assume quello del proprietario del file. -Analogamente il \textit{set-group-ID bit} o sgid settato per un file ha lo -stesso effetto sull'\textit{effective group id}. -Questa caratteristica viene usata per permettere agli utenti normali di usare -programmi che abbisognano di privilegi speciali; l'esempio classico è il -comando \cmd{passwd} che ha la necessità di modificare il file delle password, -che può essere scritto solo dall'amministratore. Per questo il comando -\cmd{passwd} appartiene a root e ha il suid bit settato per cui quando viene -lanciato da un utente normale ha comunque i privilegi di root. +\subsection{La titolarità di nuovi file e directory} +\label{sec:file_ownership} -Chiaramente avere un processo che ha privilegi superiori a quelli che avrebbe -normalmente un utente comporta vari rischi, e questo tipo di programmi devono -essere scritti accuratamente (torneremo sull'argomento in -\secref{sec:prochand_perms}). +Vedremo in \secref{sec:file_base_func} come creare nuovi file, ma se è +possibile specificare in sede di creazione quali permessi applicare ad un +file, non si può indicare a quale utente e gruppo esso deve appartenere. Lo +stesso problema di presenta per la creazione di nuove directory (procedimento +descritto in \secref{sec:file_dir_creat_rem}). -I due bit suid e sgid possono essere controllati all'interno di \var{st\_mode} -con l'uso delle due costanti \macro{S\_ISUID} e \macro{S\_ISGID}, definite in -\tabref{tab:filedir_file_mode_flags}. +Lo standard POSIX prescrive che l'uid del nuovo file corrisponda +all'\textit{effective user id} del processo che lo crea; per il gid invece +prevede due diverse possibilità: +\begin{itemize} +\item il gid del file corrisponde all'\textit{effective group id} del processo. +\item il gid del file corrisponde al gid della directory in cui esso è creato. +\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 gid +del processo, se però la directory in cui viene creato il file ha il bit +\textsl{sgid} settato allora viene usata la seconda opzione.. + +Usare la semantica BSD ha il vantaggio che il gid viene sempre automaticamente +propagato, restando coerente a quello della directory di partenza, in tutte le +sottodirectory. La semantica SVR4 offre una maggiore possibilità di scelta, ma +per ottenere lo stesso risultato necessita che per le nuove directory venga +anche propagato anche il bit sgid. Questo è comunque il comportamento di +default di \func{mkdir}, ed é in questo modo ad esempio che Debian assicura +che le sottodirectory create nelle home di un utente restino sempre con il gid +del gruppo primario dello stesso. -\subsection{Il flag \texttt{sticky}} -\label{sec:filedir_sticky} +\subsection{La funzione \texttt{access}} +\label{sec:file_access} -L'ultimo +Come detto in \secref{sec:file_access_control} il controllo di accesso ad +un file viene fatto usando \textit{effective user id} e \textit{effective + group id} del processo, ma ci sono casi in cui si può voler effettuare il +controllo usando il \textit{real user id} e il \textit{real group id} (cioè +l'uid dell'utente che ha lanciato il programma, che, come accennato in +\secref{sec:file_suid_sgid} e spiegato in \secref{sec:proc_perms} non è +detto sia uguale all'\textit{effective user id}). Per far questo si può usare +la funzione \func{access}, il cui prototipo è: -\subsection{La titolarità di nuovi files e directory} -\label{sec:filedir_ownership} +\begin{prototype}{unistd.h} +{int access(const char *pathname, int mode)} + La funzione verifica i permessi di accesso, indicati da \var{mode}, per il + file indicato da \var{pathname}. + + La funzione ritorna 0 se l'accesso è consentito, -1 altrimenti; in + quest'ultimo caso la variabile \texttt{errno} viene settata secondo i codici + di errore: \macro{EACCES}, \macro{EROFS}, \macro{EFAULT}, \macro{EINVAL}, + \macro{ENAMETOOLONG}, \macro{ENOENT}, \macro{ENOTDIR}, \macro{ELOOP}, + \macro{EIO}. +\end{prototype} -\subsection{La funzione \texttt{access}} -\label{sec:filedir_access} +I valori possibili per il parametro \var{mode} sono esprimibili come +combinazione delle costanti numeriche riportate in \ntab\ (attraverso un OR +binario). I primi tre valori implicano anche la verifica dell'esistenza del +file, se si vuole verificare solo quest'ultimaa si può usare \macro{F\_OK}, o +anche direttamente \func{stat}. In caso \var{pathname} si riferisca ad un link +simbolico il controllo è fatto sul file a cui esso fa riferimento. +La funzione controlla solo i bit dei permessi di accesso, si ricordi che il +fatto che una directory abbia permesso di scrittura non significa che ci si +possa scrivere come in un file, e il fatto che un file abbia permesso di +esecuzione non comporta che contenga un programma eseguibile. La funzione +ritorna zero solo se tutte i permessi controllati sono disponibili, in caso +contrario (o di errore) ritorna -1. -\subsection{La funzione \texttt{umask}} -\label{sec:filedir_umask} +\begin{table}[htb] + \centering + \begin{tabular}{|c|l|} + \hline + \var{mode} & Significato \\ + \hline + \hline + \macro{R\_OK} & verifica il permesso di lettura \\ + \macro{W\_OK} & verifica il permesso di scritture \\ + \macro{X\_OK} & verifica il permesso di esecuzione \\ + \macro{F\_OK} & verifica l'esistenza del file \\ + \hline + \end{tabular} + \caption{Valori possibile per il parametro \var{mode} della funzione + \func{access}} + \label{tab:file_access_mode_val} +\end{table} + +Un esempio tipico per l'uso di questa funzione è quello di un processo che sta +eseguendo un programma coi privilegi di un altro utente (attraverso l'uso del +suid bit) che vuole controllare se l'utente originale ha i permessi per +accedere ad un certo file. \subsection{Le funzioni \texttt{chmod} e \texttt{fchmod}} -\label{sec:filedir_chmod} +\label{sec:file_chmod} + +Per cambiare i permessi di un file il sistema mette ad disposizione due +funzioni, che operano rispettivamente su un filename e su un file descriptor, +i cui prototipi sono: + +\begin{functions} + \headdecl{sys/types.h} + \headdecl{sys/stat.h} + + \funcdecl{int chmod(const char *path, mode\_t mode)} Cambia i permessi del + file indicato da \var{path} al valore indicato da \var{mode}. + + \funcdecl{int fchmod(int fd, mode\_t mode)} Analoga alla precedente, ma usa + il file descriptor \var{fd} per indicare il file. + + Le funzioni restituiscono zero in caso di successo e -1 per un errore, in + caso di errore \texttt{errno} può assumere i valori: + \begin{errlist} + \item \macro{EPERM} L'\textit{effective user id} non corrisponde a quello + del proprietario del file o non è zero. + \end{errlist} + ed inoltre \macro{EROFS} e \macro{EIO}; \func{chmod} restituisce anche + \macro{EFAULT}, \macro{ENAMETOOLONG}, \macro{ENOENT}, \macro{ENOMEM}, + \macro{ENOTDIR}, \macro{EACCES}, \macro{ELOOP}; \func{fchmod} anche + \macro{EBADF}. +\end{functions} + +I valori possibili per \var{mode} sono indicati in \ntab. I valori possono +esser combinati con l'OR binario delle relative macro, o specificati +direttamente, come per l'analogo comando di shell, con il valore ottale. Ad +esempio i permessi standard assegnati ai nuovi file (lettura e scrittura per +il proprietario, sola lettura per il gruppo e gli altri) sono corrispondenti +al valore ottale $0644$, un programma invece avrebbe anche il bit di +esecuzione attivo, con un valore di $0755$, se si volesse attivare il bit suid +il valore da fornire sarebbe $4755$. + +\begin{table}[!htb] + \centering + \begin{tabular}[c]{|c|c|l|} + \hline + \var{mode} & Valore & Significato \\ + + \hline + \hline + \macro{S\_ISUID} & 04000 & set user ID \\ + \macro{S\_ISGID} & 02000 & set group ID \\ + \macro{S\_ISVTX} & 01000 & sticky bit \\ + \hline + \macro{S\_IRWXU} & 00700 & l'utente ha tutti i permessi \\ + \macro{S\_IRUSR} & 00400 & l'utente ha il permesso di lettura \\ + \macro{S\_IWUSR} & 00200 & l'utente ha il permesso di scrittura \\ + \macro{S\_IXUSR} & 00100 & l'utente ha il permesso di esecuzione \\ + \hline + \macro{S\_IRWXG} & 00070 & il gruppo ha tutti i permessi \\ + \macro{S\_IRGRP} & 00040 & il gruppo ha il permesso di lettura \\ + \macro{S\_IWGRP} & 00020 & il gruppo ha il permesso di scrittura \\ + \macro{S\_IXGRP} & 00010 & il gruppo ha il permesso di esecuzione \\ + \hline + \macro{S\_IRWXO} & 00007 & gli altri hanno tutti i permessi \\ + \macro{S\_IROTH} & 00004 & gli altri hanno il permesso di lettura \\ + \macro{S\_IWOTH} & 00002 & gli altri hanno il permesso di scrittura \\ + \macro{S\_IXOTH} & 00001 & gli altri hanno il permesso di esecuzione \\ + \hline + \end{tabular} + \caption{I valori delle costanti usate per indicare i permessi dei file.} + \label{tab:file_permission_const} +\end{table} + +Il cambiamento dei permessi di un file attraverso queste funzioni ha comunque +alcune limitazioni, provviste per motivi di sicurezza. Questo significa che +anche se si è proprietari del file non tutte le operazioni sono permesse, in +particolare: +\begin{itemize} +\item siccome solo l'amministratore può settare lo \textit{sticky bit} se se + l'\textit{effective user id} del processo non è zero esso viene + automaticamente cancellato (senza notifica di errore) qualora sia stato + indicato in \var{mode}. +\item per via della semantica SVR4 nella creazione dei nuovi file, si può + avere il caso in cui il file creato da un processo è assegnato a un gruppo + per il quale il processo non ha privilegi. Per evitare che si possa + assegnare il bit \textsl{sgid} ad un file appartenente a un gruppo per cui + non si hanno diritti, questo viene automaticamente cancellato (senza + notifica di errore) da \var{mode} qualora il gruppo del file non corrisponda + a quelli associati al processo (la cosa non avviene quando + l'\textit{effective user id} del processo è zero). +\end{itemize} + +Per alcuni filesystem\footnote{il filesystem \textsl{ext2} supporta questa + caratteristica, che è mutuata da BSD.} è inoltre prevista una ulteriore +misura di sicurezza, volta ad scongiurare l'abuso dei bit \acr{suid} e +\acr{sgid}; essa consiste nel cancellare automaticamente questi bit qualora un +processo che non appartenga all'amministratore scriva su un file. In questo +modo anche se un utente malizioso scopre un file \acr{suid} su cui può +scrivere, un eventuale modifica comporterà la perdita di ogni ulteriore +privilegio. + + +\subsection{La funzione \texttt{umask}} +\label{sec:file_umask} + +Oltre che dai valori indicati in sede di creazione, i permessi assegnati ai +nuovi file sono controllati anche da una maschera di bit settata con la +funzione \func{umask}, il cui prototipo è: + +\begin{prototype}{stat.h} +{mode\_t umask(mode\_t mask)} + + Setta la maschera dei permessi dei bit al valore specificato da \var{mask} + (di cui vengono presi solo i 9 bit meno significativi). + + La funzione ritorna il precedente valore della maschera. È una delle poche + funzioni che non restituisce codici di errore. +\end{prototype} + +Questa maschera è una caratteristica di ogni processo e viene utilizzata per +impedire che alcuni permessi possano essere assegnati ai nuovi file in sede di +creazione, i bit indicati nella maschera vengono infatti esclusi quando un +nuovo file viene creato. + +In genere questa maschera serve per impostare un default che escluda alcuni +permessi (usualmente quello di scrittura per il gruppo e gli altri, +corrispondente ad un valore di $022$). Essa è utile perché le routine +dell'interfaccia ANSI C degli stream non prevedono l'esistenza dei permessi, e +pertanto tutti i nuovi file vengono sempre creati con un default di $666$ +(cioè permessi di lettura e scrittura per tutti, si veda +\tabref{tab:file_permission_const} per un confronto); in questo modo è +possibile cancellare automaticamente i permessi non voluti, senza doverlo fare +esplicitamente. + +In genere il valore di \func{umask} viene stabilito una volta per tutte al +login a $022$, e di norma gli utenti non hanno motivi per modificarlo. Se però +si vuole che un processo possa creare un file che chiunque possa leggere +allora occorrerà cambiare il valore di \func{umask}. \subsection{Le funzioni \texttt{chown}, \texttt{fchown} e \texttt{lchown}} -\label{sec:filedir_chown} +\label{sec:file_chown} +Come per i permessi, il sistema fornisce anche delle funzioni che permettano +di cambiare utente e gruppo cui il file appartiene; le funzioni in questione +sono tre e i loro prototipi sono i seguenti: +\begin{functions} + \headdecl{sys/types.h} + \headdecl{sys/stat.h} + + \funcdecl{int chown(const char *path, uid\_t owner, gid\_t group)} + \funcdecl{int fchown(int fd, uid\_t owner, gid\_t group)} + \funcdecl{int lchown(const char *path, uid\_t owner, gid\_t group)} + Le funzioni cambiano utente e gruppo di appartenenza di un file ai valori + specificati dalle variabili \var{owner} e \var{group}. + + 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 \macro{EPERM} L'\textit{effective user id} non corrisponde a quello + del proprietario del file o non è zero, o utente e gruppo non sono validi + \end{errlist} + Oltre a questi entrambe restituiscono gli errori \macro{EROFS} e + \macro{EIO}; \func{chown} restituisce anche \macro{EFAULT}, + \macro{ENAMETOOLONG}, \macro{ENOENT}, \macro{ENOMEM}, \macro{ENOTDIR}, + \macro{EACCES}, \macro{ELOOP}; \func{fchown} anche \macro{EBADF}. +\end{functions} + +In Linux soltanto l'amministratore può cambiare il proprietario di un file, +seguendo la semantica di BSD che non consente agli utenti di assegnare i loro +file ad altri (per evitare eventuali aggiramenti delle quote). +L'amministratore può cambiare il gruppo di un file, il proprietario può +cambiare il gruppo dei file che gli appartengono solo se il nuovo gruppo è il +suo gruppo primario o uno dei gruppi a cui appartiene. + +La funzione \func{chown} segue i link simbolici, per operare direttamente su +in link simbolico si deve usare la funzione \func{lchown}\footnote{fino alla + versione 2.1.81 in Linux \func{chown} non seguiva i link simbolici, da + allora questo comportamento è stato assegnato alla funzione \func{lchown}, + introdotta per l'occazione, ed è stata creata una nuova system call per + \func{chown} che seguisse i link simbolici}. La funzione \func{fchown} opera +su un file aperto, essa è mututata da BSD, ma non è nello standard POSIX. +Un'altra estensione rispetto allo standard POSIX è che specificando -1 come +valore per \var{owner} e \var{group} i valori restano immutati. + +Quando queste funzioni sono chiamate con successo da un processo senza i +privilegi di root entrambi i bit \textsl{suid} e \textsl{sgid} vengono +cancellati. Questo non avviene per il bit \textsl{sgid} nel caso in cui esso +sia usato (in assenza del corrispondente permesso di esecuzione) per indicare +che per il file è attivo il \textit{mandatory locking}. %La struttura fondamentale che contiene i dati essenziali relativi ai file è il %cosiddetto \textit{inode}; questo conterrà informazioni come il @@ -258,24 +605,26 @@ L'ultimo \section{La manipolazione delle caratteristiche dei files} -\label{sec:filedir_infos} +\label{sec:file_infos} + +Come spiegato in \secref{sec:file_filesystem} tutte le informazioni +generali relative alle caratteristiche di ciascun file, a partire dalle +informazioni relative al controllo di accesso, sono mantenute nell'inode. -Come spiegato in \secref{sec:fileintr_filesystem} tutte le informazioni -generali relative alle caratteristiche di ciascun file sono mantenute -nell'inode. Vedremo in questa sezione come sia possibile accedervi usando la -funzione \texttt{stat} ed esamineremo alcune funzioni utilizzabili per -manipolare una parte di questa informazione. Tutto quello che invece riguarda -il meccanismo di controllo di accesso ad i file e le relative funzioni di -manipolazione sarà invece esaminanto in \secref{sec:filedir_access_control}. +Vedremo in questa sezione come sia possibile leggere tutte queste informazioni +usando la funzione \texttt{stat}, che permette l'accesso a tutti i dati +memorizzati nell'inode; esamineremo poi le varie funzioni usate per manipolare +tutte queste informazioni (eccetto quelle che riguardano la gestione del +controllo di accesso, già trattate in in \secref{sec:file_access_control}). \subsection{Le funzioni \texttt{stat}, \texttt{fstat} e \texttt{lstat}} -\label{sec:filedir_stat} +\label{sec:file_stat} La lettura delle informazioni relative ai file è fatta attraverso la famiglia -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: +delle funzioni \func{stat}; questa è la funzione che il comando \cmd{ls} usa +per poter ottenere e mostrare tutti i dati dei files. I prototipi di queste +funzioni sono i seguenti: \begin{functions} \headdecl{sys/types.h} \headdecl{sys/stat.h} @@ -294,17 +643,9 @@ i seguenti: 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 - del processo. - \item \texttt{ENOMEM} il kernel non ha a disposizione memoria sufficiente a - completare l'operazione. - \item \texttt{ENAMETOOLONG} il filename è troppo lungo. - \end{errlist} + caso di errore \texttt{errno} può assumere uno dei valori: \macro{EBADF}, + \macro{ENOENT}, \macro{ENOTDIR}, \macro{ELOOP}, \macro{EFAULT}, + \macro{EACCESS}, \macro{ENOMEM}, \macro{ENAMETOOLONG}. \end{functions} La struttura \texttt{stat} è definita nell'header \texttt{sys/stat.h} e in @@ -338,7 +679,7 @@ struct stat { \normalsize \caption{La struttura \texttt{stat} per la lettura delle informazioni dei file} - \label{fig:filedir_stat_struct} + \label{fig:file_stat_struct} \end{figure} Si noti come i vari membri della struttura siano specificati come tipi nativi @@ -347,11 +688,12 @@ del sistema (di quelli definiti in \tabref{tab:xxx_sys_types}, e dichiarati in \subsection{I tipi di file} -\label{sec:filedir_file_types} +\label{sec:file_types} -Come riportato in \tabref{tab:fileintr_file_types} in Linux oltre ai file e +Come riportato in \tabref{tab:file_file_types} in Linux oltre ai file e alle directory esistono vari altri oggetti che possono stare su un filesystem; -il tipo di file è ritornato dalla \texttt{stat} nel campo \texttt{st\_mode}. +il tipo di file è ritornato dalla \texttt{stat} nel campo \texttt{st\_mode} +(che è quello che contiene anche le informazioni relative ai permessi). Dato che il valore numerico può variare a seconda delle implementazioni, lo standard POSIX definisce un insieme di macro per verificare il tipo di files, @@ -376,7 +718,7 @@ definite in GNU/Linux \hline \end{tabular} \caption{Macro per i tipi di file (definite in \texttt{sys/stat.h})} - \label{tab:filedir_file_type_macro} + \label{tab:file_type_macro} \end{table} Oltre a queste macro è possibile usare direttamente il valore di @@ -404,17 +746,17 @@ per questo sempre in \texttt{sys/stat.h} sono definiti i flag riportati in \macro{S\_ISGID} & 0002000 & set GID bit \\ \macro{S\_ISVTX} & 0001000 & sticky bit \\ \hline - \macro{S\_IRWXU} & 00700 & bitmask per i permessi del proprietario \\ +% \macro{S\_IRWXU} & 00700 & bitmask per i permessi del proprietario \\ \macro{S\_IRUSR} & 00400 & il proprietario ha permesso di lettura \\ \macro{S\_IWUSR} & 00200 & il proprietario ha permesso di scrittura \\ \macro{S\_IXUSR} & 00100 & il proprietario ha permesso di esecuzione\\ \hline - \macro{S\_IRWXG} & 00070 & bitmask per i permessi del gruppo \\ +% \macro{S\_IRWXG} & 00070 & bitmask per i permessi del gruppo \\ \macro{S\_IRGRP} & 00040 & il gruppo ha permesso di lettura \\ \macro{S\_IWGRP} & 00020 & il gruppo ha permesso di scrittura \\ \macro{S\_IXGRP} & 00010 & il gruppo ha permesso di esecuzione \\ \hline - \macro{S\_IRWXO} & 00007 & bitmask per i permessi di tutti gli altri\\ +% \macro{S\_IRWXO} & 00007 & bitmask per i permessi di tutti gli altri\\ \macro{S\_IROTH} & 00004 & gli altri hanno permesso di lettura \\ \macro{S\_IWOTH} & 00002 & gli altri hanno permesso di esecuzione \\ \macro{S\_IXOTH} & 00001 & gli altri hanno permesso di esecuzione \\ @@ -422,7 +764,7 @@ per questo sempre in \texttt{sys/stat.h} sono definiti i flag riportati in \end{tabular} \caption{Costanti per l'identificazione dei vari bit che compongono il campo \var{st\_mode} (definite in \texttt{sys/stat.h})} - \label{tab:filedir_file_mode_flags} + \label{tab:file_mode_flags} \end{table} Il primo valore definisce la maschera dei bit usati nei quali viene @@ -436,10 +778,11 @@ un file ordinario si potrebbe definire la condizione: 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} +\label{sec:file_file_size} -Il membro \var{st\_size} contiene la dimensione del file in bytes (se il file +Il membro \var{st\_size} contiene la dimensione del file in byte (se il file è un file normale, nel caso di un link simbolico al dimensione è quella del pathname che contiene). @@ -453,7 +796,7 @@ Si tenga conto che lunghezza del file riportata in \var{st\_size} non 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 +una \func{seek} (vedi \secref{sec:file_lseek}) oltre la sua conclusione corrente. In tal caso si avranno differenti risultati a seconda del modi in cui si @@ -478,21 +821,24 @@ le due funzioni: \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}, + 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: + caso di errore \texttt{errno} viene settato opportunamente; per + \func{ftruncate} si hanno i valori: + \begin{errlist} + \item \macro{EBADF} \var{fd} non è un file descriptor. + \item \texttt{EINVAL} \var{fd} è un riferimento ad un socket, non a un file + o non è aperto in scrittura. + \end{errlist} + per \func{truncate} si hanno: \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. + \item \texttt{EACCES} il file non ha permesso di scrittura o non si ha il + permesso di esecuzione una delle directory del pathname. + \item \texttt{ETXTBSY} Il file è un programma in esecuzione. \end{errlist} + ed anche \macro{ENOTDIR}, \macro{ENAMETOOLONG}, \macro{ENOENT}, + \macro{EROFS}, \macro{EIO}, \macro{EFAULT}, \macro{ELOOP}. \end{functions} Se il file è più lungo della lunghezza specificata i dati in eccesso saranno @@ -503,12 +849,12 @@ zeri (e in genere si ha la creazione di un hole nel file). \subsection{I tempi dei file} -\label{sec:filedir_file_times} +\label{sec:file_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 significato di detti tempi e +struttura in \figref{fig:file_stat_struct}. Il significato di detti tempi e dei relativi campi è riportato nello schema in \ntab: \begin{table}[htb] @@ -525,7 +871,7 @@ dei relativi campi \hline \end{tabular} \caption{I tre tempi associati a ciascun file} - \label{tab:filedir_file_times} + \label{tab:file_file_times} \end{table} Il primo punto da tenere presente è la differenza fra il cosiddetto tempo di @@ -624,7 +970,7 @@ cambiarne i permessi ha effetti solo sui tempi del file. \caption{Effetti delle varie funzioni su tempi di ultimo accesso \textsl{(a)}, ultima modifica \textsl{(m)} e ultimo cambiamento \textsl{(c)}} - \label{tab:filedir_times_effects} + \label{tab:file_times_effects} \end{table} Si noti infine come \var{st\_ctime} non abbia nulla a che fare con il tempo di @@ -633,7 +979,7 @@ esiste. \subsection{La funzione \texttt{utime}} -\label{sec:filedir_utime} +\label{sec:file_utime} I tempi di ultimo accesso e modifica possono essere cambiati usando la funzione \func{utime}, il cui prototipo è: @@ -678,12 +1024,9 @@ molto pi - - - \section{La manipolazione di file e directory} -Come già accennato in \secref{sec:fileintr_filesystem} in un sistema unix-like +Come già accennato in \secref{sec:file_filesystem} in un sistema unix-like i file hanno delle caratteristiche specifiche dipendenti dall'architettura del sistema, esamineremo qui allora le funzioni usate per la creazione di link simbolici e diretti e per la gestione delle directory, approfondendo quanto @@ -691,7 +1034,7 @@ gi \subsection{Le funzioni \texttt{link} e \texttt{unlink}} -\label{sec:fileintr_link} +\label{sec:file_link} Una delle caratteristiche comuni a vari sistemi operativi è quella di poter creare dei nomi fittizi (alias o collegamenti) per potersi riferire allo @@ -700,7 +1043,7 @@ ambiente unix, dove tali collegamenti sono usualmente chiamati \textit{link}, ma data la struttura del sistema ci sono due metodi sostanzialmente diversi per fare questa operazione. -Come spiegato in \secref{sec:fileintr_architecture} l'accesso al contenuto di +Come spiegato in \secref{sec:file_architecture} l'accesso al contenuto di un file su disco avviene attraverso il suo inode, e il nome che si trova in una directory è solo una etichetta associata ad un puntatore a detto inode. Questo significa che la realizzazione di un link è immediata in quanto uno @@ -740,7 +1083,7 @@ controllare con il campo \var{st\_nlink} di \var{stat}) aggiungendo il nuovo nome ai precedenti. Si noti che uno stesso file può essere così richiamato in diverse directory. -Per quanto dicevamo in \secref{sec:fileintr_filesystem} la creazione del +Per quanto dicevamo in \secref{sec:file_filesystem} la creazione del collegamento diretto è possibile solo se entrambi i pathname sono nello stesso filesystem; inoltre il filesystem deve supportare i collegamenti diretti (non è il caso ad esempio del filesystem \texttt{vfat} di windows). @@ -749,7 +1092,7 @@ La funzione opera sui file ordinari, come sugli altri oggetti del filesystem, 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 +\secref{sec:file_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 è @@ -773,7 +1116,7 @@ effettua con la funzione \texttt{unlink}; il suo prototipo (valore specifico ritornato da linux che non consente l'uso di \texttt{unlink} con le directory, e non conforme allo standard POSIX, che prescrive invece l'uso di \texttt{EPERM} in caso l'operazione non sia - consnetita o il processo non abbia privilegi sufficienti). + consentita o il processo non abbia privilegi sufficienti). \item \texttt{EROFS} \var{pathname} è su un filesystem montato in sola lettura. \item \texttt{EISDIR} \var{pathname} fa riferimento a una directory. @@ -804,11 +1147,11 @@ crash dei programmi; la tecnica \texttt{unlink} subito dopo. \subsection{Le funzioni \texttt{remove} e \texttt{rename}} -\label{sec:fileintr_remove} +\label{sec:file_remove} Al contrario di quanto avviene con altri unix in Linux non è possibile usare \texttt{unlink} sulle directory, per cancellare una directory si può usare la -funzione \texttt{rmdir} (vedi \secref{sec:filedir_dir_creat_rem}), oppure la +funzione \texttt{rmdir} (vedi \secref{sec:file_dir_creat_rem}), oppure la funzione \texttt{remove}. Questa è la funzione prevista dallo standard ANSI C per cancellare un file o una directory (e funziona anche per i sistemi che non supportano i link diretti), che per i file è identica alla \texttt{unlink} e @@ -855,8 +1198,6 @@ nuovo nome dopo che il vecchio \item \texttt{ENOTDIR} Uno dei componenti dei pathname non è una directory o\texttt{oldpath} è una directory e \texttt{newpath} esiste e non è una directory. - \item \texttt{EFAULT} o \texttt{oldpath} o \texttt{newpath} è fuori dello - spazio di indirizzi del processo. \item \texttt{EACCESS} Non c'è il permesso di scrittura per la directory in cui si vuole creare il nuovo link o una delle directory del pathname non consente la ricerca (permesso di esecuzione). @@ -864,21 +1205,13 @@ nuovo nome dopo che il vecchio \texttt{newpath} hanno lo sticky bit attivo e i permessi del processo non consentono rispettivamente la cancellazione e la creazione del file, o il filesystem non supporta i link. - \item \texttt{ENAMETOOLONG} uno dei pathname è troppo lungo. - \item \texttt{ENOENT} Uno dei componenti del pathname non esiste o è un link - simbolico spezzato. - \item \texttt{ENOMEM} il kernel non ha a disposizione memoria sufficiente a - completare l'operazione. - \item \texttt{EROFS} I file sono su un filesystem montato in sola lettura. - \item \texttt{ELOOP} Ci sono troppi link simbolici nella risoluzione del - pathname. \item \texttt{ENOSPC} Il device di destinazione non ha più spazio per la nuova voce. \end{errlist} \end{prototype} \subsection{I link simbolici} -\label{sec:fileintr_symlink} +\label{sec:file_symlink} Siccome la funzione \texttt{link} crea riferimenti agli inodes, essa può funzionare soltanto per file che risiedono sullo stesso filesystem, dato che @@ -913,8 +1246,8 @@ dichiarate nell'header file \texttt{unistd.h}. La funzione restituisce zero in caso di successo e -1 per un errore, in caso di errore. La variabile \texttt{errno} viene settata secondo i codici di - errore standard di accesso ai files (trattati in dettaglio in - \secref{sec:filedir_access_control}) ai quali si aggiungono i seguenti: + errore standard di accesso ai file (trattati in dettaglio in + \secref{sec:file_access_control}) ai quali si aggiungono i seguenti: \begin{errlist} \item \texttt{EEXIST} Un file (o una directory) con quel nome esiste di già. @@ -948,8 +1281,6 @@ questa funzione su un filesystem montato readonly. \item \texttt{ENOSPC} La directory o il filesystem in cui si vuole creare il link è piena e non c'è ulteriore spazio disponibile. - \item \texttt{ELOOP} Ci sono troppi link simbolici nella risoluzione di - \texttt{oldname} o di \texttt{newname}. \end{errlist} \end{prototype} @@ -988,18 +1319,18 @@ link simbolico e quali possono operare direttamente sul suo contenuto. \hline \end{tabular} \caption{Uso dei link simbolici da parte di alcune funzioni.} - \label{tab:filedir_symb_effect} + \label{tab:file_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 +genere effettuata 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} + \label{fig:file_link_loop} \end{figure} Un caso comune che si può avere con i link simbolici è la creazione dei @@ -1013,9 +1344,13 @@ interno un link simbolico che punta di nuovo a \file{/boot}\footnote{Questo (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 +Questo può causare problemi per tutti quei programmi che effettuano lo scan di +una directory senza tener conto dei link simbolici, ad esempio se lanciassimo +un comando del tipo \cmd{grep -r linux *}, il loop nella directory porterebbe +il comando ad esaminare \file{/boot}, \file/{boot/boot}, \file/{boot/boot/boot} +e così via, fino a generare un errore (che poi è \macro{ELOOP}) quando viene +superato il numero massimo di link simbolici consentiti (uno dei limiti del +sistema, posto proprio per poter uscire da questo tipo di situazione). 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 @@ -1035,7 +1370,7 @@ di \file{temporaneo}. \subsection{Le funzioni \texttt{mkdir} e \texttt{rmdir}} -\label{sec:filedir_dir_creat_rem} +\label{sec:file_dir_creat_rem} Per creare una nuova directory si può usare la seguente funzione, omonima dell'analogo comando di shell \texttt{mkdir}; per accedere ai tipi usati @@ -1044,13 +1379,13 @@ programma deve includere il file \texttt{sys/types.h}. \begin{prototype}{sys/stat.h} {int mkdir (const char * dirname, mode\_t mode)} Questa funzione crea una nuova directory vuota con il nome indicato da - \texttt{dirname}, assegnandole i permessi indicati da \texttt{mode}. Il nome + \var{dirname}, assegnandole i permessi indicati da \var{mode}. Il nome può essere indicato con il pathname assoluto o relativo. La funzione restituisce 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 - \secref{sec:filedir_access_control}) ai quali si aggiungono i seguenti: + di accesso ai file (trattati in dettaglio in + \secref{sec:file_access_control}) ai quali si aggiungono i seguenti: \begin{errlist} \item \texttt{EACCESS} Non c'è il permesso di scrittura per la directory in cui si vuole inserire @@ -1070,7 +1405,7 @@ programma deve includere il file \texttt{sys/types.h}. \subsection{Accesso alle directory} -\label{sec:filedir_dir_read} +\label{sec:file_dir_read} Benché le directory siano oggetti del filesystem come tutti gli altri non ha ovviamente senso aprirle come fossero dei file di dati. Può però essere utile @@ -1082,12 +1417,12 @@ Per accedere al contenuto delle directory si usano i cosiddetti la funzione \texttt{opendir} apre uno di questi stream e la funzione \texttt{readdir} legge il contenuto della directory, i cui elementi sono le \textit{directory entries} (da distinguersi da quelle della cache di cui -parlavamo in \secref{sec:fileintr_vfs}) in una opportuna struttura +parlavamo in \secref{sec:file_vfs}) in una opportuna struttura \texttt{struct dirent}. \subsection{La directory di lavoro} -\label{sec:filedir_work_dir} +\label{sec:file_work_dir} A ciascun processo è associato ad una directory nel filesystem che è chiamata directory corrente o directory di lavoro (\textit{current working directory}) @@ -1159,8 +1494,8 @@ per cambiare directory di lavoro. 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 - \secref{sec:filedir_access_control}) ai quali si aggiunge il codice + errore standard di accesso ai file (trattati in dettaglio in + \secref{sec:file_access_control}) ai quali si aggiunge il codice \texttt{ENOTDIR} nel caso il \texttt{filename} indichi un file che non sia una directory. \end{prototype}