X-Git-Url: https://gapil.gnulinux.it/gitweb/?a=blobdiff_plain;f=filedir.tex;h=3c3271509fd045fe11fa868b76ae50b2327f2296;hb=975734ea91207bfbf931d2dc3bff62510087d5ba;hp=3aae3d7986a96f74f1ccebec0a020b31d092cb81;hpb=ee800a27585aeed2f753222dc5ff56fe0bcfb6e0;p=gapil.git diff --git a/filedir.tex b/filedir.tex index 3aae3d7..3c32715 100644 --- a/filedir.tex +++ b/filedir.tex @@ -215,11 +215,11 @@ tab.~\ref{tab:file_inode_operations} le più rilevanti. \textsl{\code{create}} & Chiamata per creare un nuovo file (vedi sez.~\ref{sec:file_open}).\\ \textsl{\code{link}} & Crea un \textit{hard link} (vedi - sez.~\ref{sec:file_link}).\\ + sez.~\ref{sec:link_symlink_rename}).\\ \textsl{\code{unlink}} & Cancella un \textit{hard link} (vedi - sez.~\ref{sec:file_link}).\\ + sez.~\ref{sec:link_symlink_rename}).\\ \textsl{\code{symlink}}& Crea un link simbolico (vedi - sez.~\ref{sec:file_symlink}).\\ + sez.~\ref{sec:link_symlink_rename}).\\ \textsl{\code{mkdir}} & Crea una directory (vedi sez.~\ref{sec:file_dir_creat_rem}).\\ \textsl{\code{rmdir}} & Rimuove una directory (vedi @@ -227,7 +227,7 @@ tab.~\ref{tab:file_inode_operations} le più rilevanti. \textsl{\code{mknod}} & Crea un file speciale (vedi sez.~\ref{sec:file_mknod}).\\ \textsl{\code{rename}} & Cambia il nome di un file (vedi - sez.~\ref{sec:file_remove}).\\ + sez.~\ref{sec:link_symlink_rename}).\\ \textsl{\code{lookup}}& Risolve il nome di un file.\\ \hline \end{tabular} @@ -448,9 +448,10 @@ opportuno tenere sempre presente che: \kstruct{inode} di fig.~\ref{fig:kstruct_inode}.} Solo quando questo contatore si annulla i dati del file possono essere effettivamente rimossi dal disco. Per questo la funzione per cancellare un file si chiama - \func{unlink} (vedi sez.~\ref{sec:file_link}), ed in realtà non cancella - affatto i dati del file, ma si limita ad eliminare la relativa voce da una - directory e decrementare il numero di riferimenti nell'\textit{inode}. + \func{unlink} (vedi sez.~\ref{sec:link_symlink_rename}), ed in realtà non + cancella affatto i dati del file, ma si limita ad eliminare la relativa voce + da una directory e decrementare il numero di riferimenti + nell'\textit{inode}. \item All'interno di ogni filesystem ogni \textit{inode} è identificato da un numero univoco. Il numero di \textit{inode} associato ad una voce in una @@ -458,15 +459,16 @@ opportuno tenere sempre presente che: che contiene riferimenti ad \textit{inode} relativi ad altri filesystem. Questa è la ragione che limita l'uso del comando \cmd{ln}, che crea una nuova voce per un file esistente con la funzione \func{link} (vedi - sez.~\ref{sec:file_link}), a operare su file nel filesystem corrente. + sez.~\ref{sec:link_symlink_rename}), a operare su file nel filesystem + corrente. \item Quando si cambia nome ad un file senza cambiare filesystem il contenuto del file non viene spostato fisicamente, viene semplicemente creata una nuova voce per l'\textit{inode} in questione e rimossa la precedente, questa è la modalità in cui opera normalmente il comando \cmd{mv} attraverso la - funzione \func{rename} (vedi sez.~\ref{sec:file_remove}). Questa operazione - non modifica minimamente neanche l'\textit{inode} del file, dato che non si - opera sul file ma sulla directory che lo contiene. + funzione \func{rename} (vedi sez.~\ref{sec:link_symlink_rename}). Questa + operazione non modifica minimamente neanche l'\textit{inode} del file, dato + che non si opera sul file ma sulla directory che lo contiene. \item Gli \textit{inode} dei file, che contengono i \textsl{metadati}, ed i blocchi di spazio disco, che contengono i dati, sono risorse indipendenti ed @@ -617,14 +619,15 @@ contenenti un gran numero di file. \subsection{La gestione dell'uso dei filesystem} -\label{sec:sys_file_config} +\label{sec:filesystem_mounting} Come accennato in sez.~\ref{sec:file_arch_overview} per poter accedere ai file occorre rendere disponibile al sistema il filesystem su cui essi sono memorizzati. L'operazione di attivazione del filesystem è chiamata -\textsl{montaggio} e per far questo in Linux si usa la funzione \funcd{mount}, -il cui prototipo è:\footnote{la funzione è una versione specifica di Linux che - usa la omonima \textit{system call} e non è portabile.} +\textsl{montaggio} e per far questo in Linux si usa la funzione di sistema +\funcd{mount}, il cui prototipo è:\footnote{la funzione è una versione + specifica di Linux che usa la omonima \textit{system call} e non è + portabile.} \begin{funcproto}{ \fhead{sys/mount.h} @@ -793,14 +796,14 @@ identificati dalle costanti riportate nell'elenco seguente: Il supporto per il \textit{bind mount} consente di superare i limiti presenti per gli \textit{hard link} (di cui parleremo in - sez.~\ref{sec:file_link}) con la possibilità di fare riferimento alla - porzione dell'albero dei file di un filesystem presente a partire da una - certa directory, utilizzando una qualunque altra directory, anche se questa - sta su un filesystem diverso. Si può così fornire una alternativa all'uso - dei link simbolici (di cui parleremo in sez.~\ref{sec:file_symlink}) che - funziona correttamente anche all'intero di un \textit{chroot} (argomento su - cui torneremo in sez.~\ref{sec:file_chroot}). -\itindend{bind~mount} + sez.~\ref{sec:link_symlink_rename}) con la possibilità di fare riferimento + alla porzione dell'albero dei file di un filesystem presente a partire da + una certa directory, utilizzando una qualunque altra directory, anche se + questa sta su un filesystem diverso. Si può così fornire una alternativa + all'uso dei link simbolici (di cui parleremo in + sez.~\ref{sec:link_symlink_rename}) che funziona correttamente anche + all'intero di un \textit{chroot} (argomento su cui torneremo in + sez.~\ref{sec:file_chroot}). \itindend{bind~mount} \item[\const{MS\_DIRSYNC}] Richiede che ogni modifica al contenuto di una directory venga immediatamente registrata su disco in maniera sincrona @@ -1070,7 +1073,8 @@ identificati dalle costanti riportate nell'elenco seguente: Una volta che non si voglia più utilizzare un certo filesystem è possibile -``\textsl{smontarlo}'' usando la funzione \funcd{umount}, il cui prototipo è: +``\textsl{smontarlo}'' usando la funzione di sistema \funcd{umount}, il cui +prototipo è: \begin{funcproto}{ \fhead{sys/mount.h} @@ -1105,9 +1109,9 @@ aperti sul filesystem, se questo contiene la \index{directory~di~lavoro} directory di lavoro di un qualunque processo o il \itindex{mount~point} \textit{mount point} di un altro filesystem. -Linux provvede inoltre una seconda funzione, \funcd{umount2}, che consente un -maggior controllo delle operazioni, come forzare lo smontaggio di un -filesystem anche quando questo risulti occupato; il suo prototipo è: +Linux provvede inoltre una seconda funzione di sistema, \funcd{umount2}, che +consente un maggior controllo delle operazioni, come forzare lo smontaggio di +un filesystem anche quando questo risulti occupato; il suo prototipo è: \begin{funcproto}{ \fhead{sys/mount.h} @@ -1159,9 +1163,9 @@ eseguita una sincronizzazione dei dati. del filesystem questo venga smontato (presente dal kernel 2.6.8 e dalla \acr{glibc} 2.11).\\ \const{UMOUNT\_NOFOLLOW}& non dereferenzia \param{target} se questo è un - link simbolico (vedi sez.~\ref{sec:file_symlink}) - evitando problemi di sicurezza (presente dal kernel - 2.6.34).\\ + link simbolico (vedi + sez.~\ref{sec:link_symlink_rename}) evitando + problemi di sicurezza (presente dal kernel 2.6.34).\\ \hline \end{tabular} \caption{Costanti che identificano i bit dell'argomento \param{flags} @@ -1186,14 +1190,14 @@ un meccanismo che smonti automaticamente i filesystem che restano inutilizzati per un certo periodo di tempo. Infine il flag \const{UMOUNT\_NOFOLLOW} non dereferenzia \param{target} se -questo è un link simbolico (vedi sez.~\ref{sec:file_symlink}). Questa è una -misura di sicurezza introdotta per evitare, per quei filesystem per il quale è -prevista una gestione diretta da parte degli utenti, come quelli basati su -FUSE,\footnote{il \textit{Filesystem in USEr space} (FUSE) è una delle più - interessanti applicazioni del \itindex{Virtual~File~System} VFS che - consente, tramite un opportuno modulo, di implementarne le funzioni in +questo è un link simbolico (vedi sez.~\ref{sec:link_symlink_rename}). Questa è +una misura di sicurezza introdotta per evitare, per quei filesystem per il +quale è prevista una gestione diretta da parte degli utenti, come quelli +basati su FUSE,\footnote{il \textit{Filesystem in USEr space} (FUSE) è una + delle più interessanti applicazioni del \itindex{Virtual~File~System} VFS + che consente, tramite un opportuno modulo, di implementarne le funzioni in \textit{user space}, così da rendere possibile l'implementazione di un - qualunque filesytem (con applicazioni di grande interesse come il filesystem + qualunque filesystem (con applicazioni di grande interesse come il filesystem cifrato \textit{encfs} o il filesystem di rete \textit{sshfs}) che possa essere usato direttamente per conto degli utenti.} che si possano passare ai programmi che effettuano lo smontaggio dei filesystem, che in genere sono @@ -1202,10 +1206,10 @@ link simbolici che puntano ad altri \textit{mount point}, ottenendo così la possibilità di smontare qualunque filesystem. -Altre due funzioni specifiche di Linux,\footnote{esse si trovano anche su BSD, - ma con una struttura diversa.} utili per ottenere in maniera diretta -informazioni riguardo al filesystem su cui si trova un certo file, sono -\funcd{statfs} e \funcd{fstatfs}, i cui prototipi sono: +Altre due funzioni di sistema specifiche di Linux,\footnote{esse si trovano + anche su BSD, ma con una struttura diversa.} utili per ottenere in maniera +diretta informazioni riguardo al filesystem su cui si trova un certo file, +sono \funcd{statfs} e \funcd{fstatfs}, i cui prototipi sono: \begin{funcproto}{ \fhead{sys/vfs.h} @@ -1245,7 +1249,7 @@ del filesystem stesso. \label{fig:sys_statfs} \end{figure} -Le \acr{glibc} provvedono infine una serie di funzioni per la gestione dei due +La \acr{glibc} provvede infine una serie di funzioni per la gestione dei due file \conffile{/etc/fstab}\footnote{più precisamente \funcm{setfsent}, \funcm{getfsent}, \funcm{getfsfile}, \funcm{getfsspec}, \funcm{endfsent}.} ed \conffile{/etc/mtab}\footnote{più precisamente \funcm{setmntent}, @@ -1270,7 +1274,7 @@ oggi sostituito da un link simbolico a \procfile{/proc/mounts}, che contiene una versione degli stessi contenuti (vale a dire l'elenco dei filesystem montati) generata direttamente dal kernel, e quindi sempre disponibile e sempre aggiornata. Per questo motivo tralasceremo la trattazione, di queste -funzioni, rimandando al manuale delle \acr{glibc} \cite{GlibcMan} per la +funzioni, rimandando al manuale della \acr{glibc} \cite{GlibcMan} per la documentazione completa. % TODO (bassa priorità) scrivere delle funzioni (getfsent e getmntent &C) @@ -1280,51 +1284,55 @@ documentazione completa. \section{La gestione di file e directory} \label{sec:file_dir} -Come già accennato in sez.~\ref{sec:file_filesystem} in un sistema unix-like -la gestione dei file ha delle caratteristiche specifiche che derivano -direttamente dall'architettura del sistema. In questa sezione esamineremo le -funzioni usate per la manipolazione di file e directory, per la creazione di -link simbolici e diretti, per la gestione e la lettura delle directory. In -particolare ci soffermeremo sulle conseguenze che derivano dalla struttura -generica di un qualunque filesystem illustrata in -sez.~\ref{sec:file_filesystem} per quanto attiene il comportamento e gli -effetti delle varie funzioni. +In questa sezione esamineremo le funzioni usate per la manipolazione dei nomi +file e directory, per la creazione di link simbolici e diretti, per la +gestione e la lettura delle directory. In particolare ci soffermeremo sulle +conseguenze che derivano dalla architettura di un filesystem unix-like +illustrata in sez.~\ref{sec:file_filesystem} per quanto attiene il +comportamento e gli effetti delle varie funzioni. Tratteremo infine la +directory di lavoro e le funzioni per la gestione di file speciali e +temporanei. + + +\subsection{La gestione dei nomi dei file} +\label{sec:link_symlink_rename} -\subsection{Le funzioni \func{link} e \func{unlink}} -\label{sec:file_link} +% \subsection{Le funzioni \func{link} e \func{unlink}} +% \label{sec:file_link} Una caratteristica comune a diversi sistemi operativi è quella di poter creare -dei nomi fittizi (come gli alias del vecchio MacOS o i collegamenti di Windows -o i nomi logici del VMS) che permettono di fare riferimento allo stesso file -chiamandolo con nomi diversi o accedendovi da directory diverse. - -Questo è possibile anche in ambiente Unix, dove tali collegamenti sono -usualmente chiamati ``\textit{link}''; ma data l'architettura del sistema -riguardo la gestione dei file ci sono due metodi sostanzialmente diversi per -fare questa operazione. - -Come spiegato in sez.~\ref{sec:file_filesystem} l'accesso al contenuto di un -file su disco avviene passando attraverso il suo \itindex{inode} -\textit{inode}, che è la struttura usata dal kernel che lo identifica -univocamente all'interno di un singolo filesystem. Il nome del file che si -trova nella voce di una directory è solo un'etichetta, mantenuta all'interno -della directory, che viene associata ad un puntatore che fa riferimento al -suddetto \textit{inode}. +dei nomi alternativi, come gli alias del vecchio MacOS o i collegamenti di +Windows o i nomi logici del VMS, che permettono di fare riferimento allo +stesso file chiamandolo con nomi diversi o accedendovi da directory diverse. +Questo è possibile anche in ambiente Unix, dove un nome alternativo viene +usualmente chiamato `` \textsl{collegamento}'' (o \textit{link}). Data +l'architettura del sistema riguardo la gestione dei file vedremo però che ci +sono due metodi sostanzialmente diversi per fare questa operazione. + +\itindbeg{hard~link} +\index{collegamento!diretto|(} + +In sez.~\ref{sec:file_filesystem} abbiamo spiegato come la capacità di +chiamare un file con nomi diversi sia connaturata con l'architettura di un +filesystem per un sistema Unix, in quanto il nome del file che si trova in una +directory è solo un'etichetta che viene associata ad un puntatore per ottenere +il riferimento ad un \textit{inode}, ed è questa la struttura che il kernel +usa per identifica univocamente gli oggetti su un filesystem. Questo significa che fintanto che si resta sullo stesso filesystem la -realizzazione di un link è immediata ed uno stesso file può avere tanti nomi -diversi, dati da altrettante associazioni diverse allo stesso \itindex{inode} -\textit{inode} effettuate tramite ``etichette'' diverse (voci, nella -nomenclatura di sez.~\ref{sec:file_filesystem}) in directory diverse. Si noti -anche che nessuno di questi nomi viene ad assumere una particolare preferenza -o originalità rispetto agli altri, in quanto tutti fanno comunque riferimento -allo stesso \itindex{inode} \textit{inode}. - -Per aggiungere ad una directory una voce che faccia riferimento ad un -\itindex{inode} \textit{inode} già esistente si utilizza la funzione -\funcd{link}, e si suole chiamare questo tipo di associazione un collegamento -diretto, o \textit{hard link}. Il prototipo della funzione è il seguente: +realizzazione di un collegamento è immediata ed uno stesso file può avere +tanti nomi diversi, dati da altrettante associazioni diverse allo stesso +\itindex{inode} \textit{inode} effettuate tramite ``etichette'' diverse in +directory diverse. Si noti anche come nessuno di questi nomi possa assumere +una particolare preferenza o originalità rispetto agli altri, in quanto tutti +fanno comunque riferimento allo stesso \itindex{inode} \textit{inode} che è +l'oggetto che identifica effettivamente il file. + +Quando si vuole aggiungere ad una directory una voce che faccia riferimento ad +un file già esistente nella modalità appena descritta, per ottenere quello che +viene denominato ``\textsl{collegamento diretto}'' (o \textit{hard link}), si +deve usare la funzione di sistema \funcd{link}, il cui prototipo è: \begin{funcproto}{ \fhead{unistd.h} @@ -1350,47 +1358,46 @@ diretto, o \textit{hard link}. Il prototipo della funzione è il seguente: generico.} \end{funcproto} - -La funzione crea sul \textit{pathname} \param{newpath} un collegamento diretto -al file indicato da \param{oldpath}. Per quanto detto la creazione di un -nuovo collegamento diretto non copia il contenuto del file, ma si limita a -creare una voce nella directory specificata da \param{newpath} e ad aumentare -di uno il numero di riferimenti al file (riportato nel campo \var{st\_nlink} -della struttura \struct{stat}, vedi sez.~\ref{sec:file_stat}) aggiungendo il -nuovo nome ai precedenti. In questo modo lo stesso file può essere chiamato -con vari nomi in diverse directory. +La funzione crea in \param{newpath} un collegamento diretto al file indicato +da \param{oldpath}. Per quanto detto la creazione di un nuovo collegamento +diretto non copia il contenuto del file, ma si limita a creare una voce +specificata da \param{newpath} nella directory corrispondente e l'unica +proprietà del file che verrà modificata sarà il numero di riferimenti al file +(il campo \var{i\_nlink} della struttura \kstruct{inode}, vedi +fig.~\ref{fig:kstruct_inode}) che verrà aumentato di di uno. In questo modo lo +stesso file potrà essere acceduto sia con \param{newpath} che +con \param{oldpath}. Per quanto dicevamo in sez.~\ref{sec:file_filesystem} la creazione di un collegamento diretto è possibile solo se entrambi i \textit{pathname} sono -nello stesso filesystem. Inoltre il filesystem deve supportare i collegamenti -diretti (il meccanismo non è disponibile ad esempio con il filesystem -\acr{vfat} di Windows). In realtà la funzione ha un ulteriore requisito, e -cioè che non solo che i due file siano sullo stesso filesystem, ma anche che -si faccia riferimento ad essi sullo stesso \itindex{mount~point} \textit{mount - point}.\footnote{si tenga presente infatti (vedi - sez.~\ref{sec:sys_file_config}) che a partire dal kernel 2.4 uno stesso +nello stesso filesystem ed inoltre esso deve supportare gli \textit{hard link} +(il meccanismo non è disponibile ad esempio con il filesystem \acr{vfat} di +Windows). In realtà la funzione ha un ulteriore requisito, e cioè che non solo +che i due file siano sullo stesso filesystem, ma anche che si faccia +riferimento ad essi all'interno dello stesso \itindex{mount~point} +\textit{mount point}.\footnote{si tenga presente infatti, come detto in + sez.~\ref{sec:filesystem_mounting}, che a partire dal kernel 2.4 uno stesso filesystem può essere montato più volte su directory diverse.} La funzione inoltre opera sia sui file ordinari che sugli altri oggetti del filesystem, con l'eccezione delle directory. In alcune versioni di Unix solo l'amministratore è in grado di creare un collegamento diretto ad un'altra directory: questo viene fatto perché con una tale operazione è possibile -creare dei \textit{loop} nel filesystem (vedi l'esempio mostrato in -sez.~\ref{sec:file_symlink}, dove riprenderemo il discorso) che molti -programmi non sono in grado di gestire e la cui rimozione diventerebbe -piuttosto complicata (in genere per questo tipo di errori occorre eseguire il -programma \cmd{fsck} per riparare il filesystem). +creare dei \textit{loop} nel filesystem (vedi fig.~\ref{fig:file_link_loop}) +che molti programmi non sono in grado di gestire e la cui rimozione +diventerebbe piuttosto complicata (in genere per questo tipo di errori occorre +eseguire il programma \cmd{fsck} per riparare il filesystem). Data la pericolosità di questa operazione e la disponibilità dei link -simbolici (che vedremo in sez.~\ref{sec:file_symlink}) e dei -\itindex{bind~mount} \textit{bind mount} (già visti in -sez.~\ref{sec:sys_file_config}) che possono fornire la stessa funzionalità -senza questi problemi, nel caso di Linux questa capacità è stata completamente -disabilitata, e al tentativo di creare un link diretto ad una directory la -funzione \func{link} restituisce l'errore \errcode{EPERM}. +simbolici (che vedremo a breve) e dei \itindex{bind~mount} \textit{bind mount} +(già visti in sez.~\ref{sec:filesystem_mounting}) che possono fornire la +stessa funzionalità senza questi problemi, nel caso di Linux questa capacità è +stata completamente disabilitata, e al tentativo di creare un collegamento +diretto ad una directory la funzione \func{link} restituisce sempre l'errore +\errcode{EPERM}. Un ulteriore comportamento peculiare di Linux è quello in cui si crea un -\textit{hard link} ad un link simbolico. In questo caso lo standard +\textit{hard link} ad un collegamento simbolico. In questo caso lo standard POSIX.1-2001 prevederebbe che quest'ultimo venga risolto e che il collegamento sia effettuato rispetto al file cui esso punta, e che venga riportato un errore qualora questo non esista o non sia un file. Questo era anche il @@ -1400,269 +1407,98 @@ comportamento iniziale di Linux ma a partire dai kernel della serie ripristinato anche durante lo sviluppo della serie 2.1.x, per poi tornare al comportamento attuale fino ad oggi (per riferimento si veda \url{http://lwn.net/Articles/293902}).} è stato adottato un comportamento -che non segue più lo standard per cui l'\textit{hard link} viene creato -rispetto al link simbolico, e non al file cui questo punta. La revisione -POSIX.1-2008 lascia invece il comportamento dipendente dall'implementazione, -cosa che rende Linux aderente allo standard. - -La ragione di questa differenza rispetto al vecchio standard, presente anche -in altri sistemi unix-like, sono dovute al fatto che un link simbolico può -fare riferimento anche ad un file non esistente o a una directory, per i quali -l'\textit{hard link} non può essere creato, per cui la scelta di seguire il -link simbolico è stata ritenuta una scelta scorretta nella progettazione -dell'interfaccia. Infatti se non ci fosse il comportamento adottato da Linux -sarebbe impossibile creare un \textit{hard link} ad un link simbolico, perché -la funzione lo risolverebbe e l'\textit{hard link} verrebbe creato verso la -destinazione. Invece evitando di seguire lo standard l'operazione diventa -possibile, ed anche il comportamento della funzione risulta molto più -comprensibile. Tanto più che se proprio se si vuole creare un \textit{hard - link} rispetto alla destinazione di un link simbolico è sempre possibile -farlo direttamente.\footnote{ciò non toglie che questo comportamento possa - causare problemi, come nell'esempio descritto nell'articolo citato nella - nota precedente, a programmi che non si aspettano questa differenza rispetto - allo standard POSIX.} - -La rimozione di un file (o più precisamente della voce che lo referenzia -all'interno di una directory) si effettua con la funzione \funcd{unlink}; il -suo prototipo è il seguente: - -\begin{funcproto}{ -\fhead{unistd.h} -\fdecl{int unlink(const char *pathname)} -\fdesc{Cancella un file.} -} -{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, - nel qual caso \var{errno} assumerà uno dei valori: - \begin{errlist} - \item[\errcode{EISDIR}] \param{pathname} si riferisce ad una - directory.\footnotemark - \item[\errcode{EROFS}] \param{pathname} è su un filesystem montato in sola - lettura. - \item[\errcode{EISDIR}] \param{pathname} fa riferimento a una directory. - \end{errlist} ed inoltre \errval{EACCES}, \errval{EFAULT}, \errval{ENOENT}, - \errval{ENOTDIR}, \errval{ENOMEM}, \errval{EROFS}, \errval{ELOOP}, - \errval{EIO} nel loro significato generico.} -\end{funcproto} - -\footnotetext{questo è un valore specifico ritornato da Linux che non consente - l'uso di \func{unlink} con le directory (vedi sez.~\ref{sec:file_remove}). - Non è conforme allo standard POSIX, che prescrive invece l'uso di - \errcode{EPERM} in caso l'operazione non sia consentita o il processo non - abbia privilegi sufficienti.} - -La funzione cancella il nome specificato da \param{pathname} nella relativa -directory e decrementa il numero di riferimenti nel relativo \itindex{inode} -\textit{inode}. Nel caso di link simbolico cancella il link simbolico; nel -caso di socket, fifo o file di dispositivo \index{file!di~dispositivo} rimuove -il nome, ma come per i file i processi che hanno aperto uno di questi oggetti -possono continuare ad utilizzarlo. - -Per cancellare una voce in una directory è necessario avere il permesso di -scrittura su di essa, dato che si va a rimuovere una voce dal suo contenuto, e -il diritto di esecuzione sulla directory che la contiene (affronteremo in -dettaglio l'argomento dei permessi di file e directory in -sez.~\ref{sec:file_access_control}). Se inoltre lo \itindex{sticky~bit} -\textit{sticky bit} (vedi sez.~\ref{sec:file_special_perm}) è impostato -occorrerà anche essere proprietari del file o proprietari della directory (o -root, per cui nessuna delle restrizioni è applicata). - -Una delle caratteristiche di queste funzioni è che la creazione/rimozione del -nome dalla directory e l'incremento/decremento del numero di riferimenti -\itindex{inode} nell'\textit{inode} devono essere effettuati in maniera -atomica (si veda sez.~\ref{sec:proc_atom_oper}) senza possibili interruzioni -fra le due operazioni. Per questo entrambe queste funzioni sono realizzate -tramite una singola system call. - -Si ricordi infine che un file non viene eliminato dal disco fintanto che tutti -i riferimenti ad esso sono stati cancellati: solo quando il \textit{link - count} mantenuto \itindex{inode} nell'\textit{inode} diventa zero lo spazio -occupato su disco viene rimosso (si ricordi comunque che a questo si aggiunge -sempre un'ulteriore condizione,\footnote{come vedremo in - cap.~\ref{cha:file_unix_interface} il kernel mantiene anche una tabella dei - file aperti nei vari processi, che a sua volta contiene i riferimenti agli - \itindex{inode} \textit{inode} ad essi relativi. Prima di procedere alla - cancellazione dello spazio occupato su disco dal contenuto di un file il - kernel controlla anche questa tabella, per verificare che anche in essa non - ci sia più nessun riferimento all'\textit{inode} in questione.} e cioè che -non ci siano processi che abbiano il suddetto file aperto). - -Questa proprietà viene spesso usata per essere sicuri di non lasciare file -temporanei su disco in caso di crash dei programmi; la tecnica è quella di -aprire il file e chiamare \func{unlink} subito dopo, in questo modo il -contenuto del file è sempre disponibile all'interno del processo attraverso il -suo file descriptor (vedi sez.~\ref{sec:file_fd}) fintanto che il processo non -chiude il file, ma non ne resta traccia in nessuna directory, e lo spazio -occupato su disco viene immediatamente rilasciato alla conclusione del -processo (quando tutti i file vengono chiusi). - - -\subsection{Le funzioni \func{remove} e \func{rename}} -\label{sec:file_remove} - -Al contrario di quanto avviene con altri Unix, in Linux non è possibile usare -\func{unlink} sulle directory; per cancellare una directory si può usare la -funzione \func{rmdir} (vedi sez.~\ref{sec:file_dir_creat_rem}), oppure la -funzione \funcd{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). Per i file è identica a \func{unlink} e per le directory è identica -a \func{rmdir}; il suo prototipo è: - -\begin{funcproto}{ -\fhead{stdio.h} -\fdecl{int remove(const char *pathname)} -\fdesc{Cancella un nome dal filesystem.} -} -{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual - caso \var{errno} assumerà uno dei valori relativi alla chiamata utilizzata, - pertanto si può fare riferimento a quanto illustrato nelle descrizioni di - \func{unlink} e \func{rmdir}.} -\end{funcproto} - -La funzione utilizza la funzione \func{unlink}\footnote{questo vale usando le - \acr{glibc}; nelle libc4 e nelle libc5 la funzione \func{remove} è un - semplice alias alla funzione \func{unlink} e quindi non può essere usata per - le directory.} per cancellare i file e la funzione \func{rmdir} per -cancellare le directory; si tenga presente che per alcune implementazioni del -protocollo NFS utilizzare questa funzione può comportare la scomparsa di file -ancora in uso. - -Per cambiare nome ad un file o a una directory (che devono comunque essere -nello stesso filesystem) si usa invece la funzione \funcd{rename},\footnote{la - funzione è definita dallo standard ANSI C, ma si applica solo per i file, lo - standard POSIX estende la funzione anche alle directory.} il cui prototipo -è: - -\begin{funcproto}{ -\fhead{stdio.h} -\fdecl{int rename(const char *oldpath, const char *newpath)} -\fdesc{Rinomina un file.} -} -{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, - nel qual caso \var{errno} assumerà uno dei valori: - \begin{errlist} - \item[\errcode{EISDIR}] \param{newpath} è una directory mentre - \param{oldpath} non è una directory. - \item[\errcode{EXDEV}] \param{oldpath} e \param{newpath} non sono sullo - stesso filesystem. - \item[\errcode{ENOTEMPTY}] \param{newpath} è una directory già esistente e - non vuota. - \item[\errcode{EBUSY}] o \param{oldpath} o \param{newpath} sono in uso da - parte di qualche processo (come \index{directory~di~lavoro} directory di - lavoro o come radice) o del sistema (come \itindex{mount~point} - \textit{mount point}). - \item[\errcode{EINVAL}] \param{newpath} contiene un prefisso di - \param{oldpath} o più in generale si è cercato di creare una directory come - sotto-directory di se stessa. - \item[\errcode{ENOTDIR}] uno dei componenti dei \textit{pathname} non è una - directory o \param{oldpath} è una directory e - \param{newpath} esiste e non è una directory. - \end{errlist} ed inoltre \errval{EACCES}, \errval{EPERM}, \errval{EMLINK}, - \errval{ENOENT}, \errval{ENOMEM}, \errval{EROFS}, \errval{ELOOP} e - \errval{ENOSPC} nel loro significato generico.} -\end{funcproto} - -La funzione rinomina il file \param{oldpath} in \param{newpath}, eseguendo se -necessario lo spostamento di un file fra directory diverse. Eventuali altri -link diretti allo stesso file non vengono influenzati. - -Il comportamento della funzione è diverso a seconda che si voglia rinominare -un file o una directory; se ci riferisce ad un file allora \param{newpath}, se -esiste, non deve essere una directory (altrimenti si ha l'errore -\errcode{EISDIR}). Nel caso \param{newpath} indichi un file esistente questo -viene cancellato e rimpiazzato (atomicamente). +che non segue più lo standard per cui l'\textit{hard link} viene creato nei +confronti del collegamento simbolico, e non del file cui questo punta. La +revisione POSIX.1-2008 lascia invece il comportamento dipendente +dall'implementazione, cosa che rende Linux aderente a questa versione +successiva dello standard. -Se \param{oldpath} è una directory allora \param{newpath}, se esiste, deve -essere una directory vuota, altrimenti si avranno gli errori \errcode{ENOTDIR} -(se non è una directory) o \errcode{ENOTEMPTY} (se non è vuota). Chiaramente -\param{newpath} non può contenere \param{oldpath} altrimenti si avrà un errore -\errcode{EINVAL}. +\itindbeg{symbolic~link} -Se \param{oldpath} si riferisce ad un link simbolico questo sarà rinominato; se -\param{newpath} è un link simbolico verrà cancellato come qualunque altro -file. Infine qualora \param{oldpath} e \param{newpath} siano due nomi dello -stesso file lo standard POSIX prevede che la funzione non dia errore, e non -faccia nulla, lasciando entrambi i nomi; Linux segue questo standard, anche -se, come fatto notare dal manuale delle \textit{glibc}, il comportamento più -ragionevole sarebbe quello di cancellare \param{oldpath}. +\index{collegamento!simbolico|(} -Il vantaggio nell'uso di questa funzione al posto della chiamata successiva di -\func{link} e \func{unlink} è che l'operazione è eseguita atomicamente, non -può esistere cioè nessun istante in cui un altro processo può trovare attivi -entrambi i nomi dello stesso file, o, in caso di sostituzione di un file -esistente, non trovare quest'ultimo prima che la sostituzione sia stata -eseguita. - -In ogni caso se \param{newpath} esiste e l'operazione fallisce per un qualche -motivo (come un crash del kernel), \func{rename} garantisce di lasciare -presente un'istanza di \param{newpath}. Tuttavia nella sovrascrittura potrà -esistere una finestra in cui sia \param{oldpath} che \param{newpath} fanno -riferimento allo stesso file. - - -\subsection{I link simbolici} -\label{sec:file_symlink} - -Come abbiamo visto in sez.~\ref{sec:file_link} la funzione \func{link} crea -riferimenti agli \itindex{inode} \textit{inode}, pertanto può funzionare -soltanto per file che risiedono sullo stesso filesystem e solo per un -filesystem di tipo Unix. Inoltre abbiamo visto che in Linux non è consentito -eseguire un link diretto ad una directory. - -Per ovviare a queste limitazioni i sistemi Unix supportano un'altra forma di -link (i cosiddetti \textit{soft link} o \textit{symbolic link}), che sono, -come avviene in altri sistemi operativi, dei file speciali che contengono -semplicemente il riferimento ad un altro file (o directory). In questo modo è -possibile effettuare link anche attraverso filesystem diversi, a file posti in -filesystem che non supportano i link diretti, a delle directory, ed anche a -file che non esistono ancora. - -Il sistema funziona in quanto i link simbolici sono riconosciuti come tali dal -kernel\footnote{è uno dei diversi tipi di file visti in +La ragione di questa differenza rispetto al vecchio standard, presente anche +in altri sistemi unix-like, sono dovute al fatto che un collegamento simbolico +può fare riferimento anche ad un file non esistente o a una directory, per i +quali l'\textit{hard link} non può essere creato, per cui la scelta di seguire +il collegamento simbolico è stata ritenuta una scelta scorretta nella +progettazione dell'interfaccia. Infatti se non ci fosse il comportamento +adottato da Linux sarebbe impossibile creare un \textit{hard link} ad un +collegamento simbolico, perché la funzione lo risolverebbe e l'\textit{hard + link} verrebbe creato verso la destinazione. Invece evitando di seguire lo +standard l'operazione diventa possibile, ed anche il comportamento della +funzione risulta molto più comprensibile. Tanto più che se proprio se si vuole +creare un \textit{hard link} rispetto alla destinazione di un collegamento +simbolico è sempre possibile farlo direttamente.\footnote{ciò non toglie che + questo comportamento possa causare problemi, come nell'esempio descritto + nell'articolo citato nella nota precedente, a programmi che non si aspettano + questa differenza rispetto allo standard POSIX.} + +Dato che \func{link} crea semplicemente dei nomi che fanno riferimenti agli +\itindex{inode} \textit{inode}, essa può funzionare soltanto per file che +risiedono sullo stesso filesystem e solo per un filesystem di tipo Unix. +Inoltre abbiamo visto che in Linux non è consentito eseguire un collegamento +diretto ad una directory. + +Per ovviare a queste limitazioni, come accennato all'inizio, i sistemi +unix-like supportano un'altra forma di collegamento, detta +``\textsl{collegamento simbolico}'' (o anche \textit{soft link} o +\textit{symbolic link}). In questo caso si tratta, come avviene in altri +sistemi operativi, di file speciali che contengono semplicemente il +riferimento ad un altro file (o directory). In questo modo è possibile +effettuare collegamenti anche attraverso filesystem diversi, a file posti in +filesystem che non supportano i collegamenti diretti, a delle directory, ed +anche a file che non esistono ancora. + +\itindend{hard~link} +\index{collegamento!diretto|)} + +Il meccanismo funziona in quanto i \textit{symbolic link} sono riconosciuti +come tali dal kernel\footnote{è uno dei diversi tipi di file visti in tab.~\ref{tab:file_file_types}, contrassegnato come tale nell'\textit{inode}, e riconoscibile dal valore del campo \var{st\_mode} - della struttura \struct{stat} (vedi sez.~\ref{sec:file_stat}).} per cui -alcune funzioni di libreria (come \func{open} o \func{stat}) quando ricevono -come argomento un link simbolico vengono automaticamente applicate al file da -esso specificato. La funzione che permette di creare un nuovo link simbolico -è \funcd{symlink}, ed il suo prototipo è: - + della struttura \struct{stat} (vedi sez.~\ref{sec:file_stat}).} e tutta una +serie di funzioni di sistema (come \func{open} o \func{stat}) quando ricevono +come argomento il \textit{pathname} di un collegamento simbolico vanno +automaticamente ad operare sul file da esso specificato. La funzione di +sistema che permette di creare un nuovo collegamento simbolico è +\funcd{symlink}, ed il suo prototipo è: \begin{funcproto}{ \fhead{unistd.h} \fdecl{int symlink(const char *oldpath, const char *newpath)} -\fdesc{Crea un nuovo link simbolico.} +\fdesc{Crea un nuovo collegamento simbolico (\textit{symbolic link}).} } {La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual caso \var{errno} assumerà uno dei valori: \begin{errlist} - \item[\errcode{EPERM}] il filesystem che contiene \param{newpath} non - supporta i link simbolici. + \item[\errcode{EEXIST}] esiste già un file \param{newpath}. \item[\errcode{ENOENT}] una componente di \param{newpath} non esiste o \param{oldpath} è una stringa vuota. - \item[\errcode{EEXIST}] esiste già un file \param{newpath}. + \item[\errcode{EPERM}] il filesystem che contiene \param{newpath} non + supporta i collegamenti simbolici. \item[\errcode{EROFS}] \param{newpath} è su un filesystem montato in sola lettura. - \end{errlist} ed inoltre \errval{EFAULT}, \errval{EACCES}, - \errval{ENAMETOOLONG}, \errval{ENOTDIR}, \errval{ENOMEM}, \errval{ELOOP}, - \errval{ENOSPC} e \errval{EIO} nel loro significato generico.} + \end{errlist} ed inoltre \errval{EACCES}, \errval{EFAULT}, \errval{EIO}, + \errval{ELOOP}, \errval{ENAMETOOLONG}, \errval{ENOMEM}, \errval{ENOSPC} e + \errval{ENOTDIR} nel loro significato generico.} \end{funcproto} -La funzione crea un nuovo link simbolico con \textit{pathname} \param{newpath} -che fa riferimento ad \param{oldpath}. Si tenga presente che la funzione non +La funzione crea un nuovo collegamento simbolico \param{newpath} che fa +riferimento ad \param{oldpath}. Si tenga presente che la funzione non effettua nessun controllo sull'esistenza di un file di nome \param{oldpath}, -ma si limita ad inserire il \textit{pathname} nel link simbolico. Pertanto un -link simbolico può anche riferirsi ad un file che non esiste: in questo caso -si ha quello che viene chiamato un \textit{dangling link}, letteralmente un -\textsl{link ciondolante}. - -Come accennato i link simbolici sono risolti automaticamente dal kernel -all'invocazione delle varie system call; in tab.~\ref{tab:file_symb_effect} si -è riportato un elenco dei comportamenti delle varie funzioni di libreria che -operano sui file nei confronti della risoluzione dei link simbolici, -specificando quali seguono il link simbolico e quali invece possono operare -direttamente sul suo contenuto. +ma si limita ad inserire il \textit{pathname} nel collegamento +simbolico. Pertanto un collegamento simbolico può anche riferirsi ad un file +che non esiste ed in questo caso si ha quello che viene chiamato un +\itindex{dangling~link} \textit{dangling link}, letteralmente un +\index{collegamento!ciondolante} ``\textsl{collegamento ciondolante}''. + +Come accennato i collegamenti simbolici sono risolti automaticamente dal +kernel all'invocazione delle varie \textit{system call}. In +tab.~\ref{tab:file_symb_effect} si è riportato un elenco dei comportamenti +delle varie funzioni di sistema che operano sui file nei confronti della +risoluzione dei collegamenti simbolici, specificando quali li seguono e quali +invece possono operare direttamente sui loro contenuti. \begin{table}[htb] \centering \footnotesize @@ -1694,12 +1530,12 @@ direttamente sul suo contenuto. \func{unlink} & -- & $\bullet$ \\ \hline \end{tabular} - \caption{Uso dei link simbolici da parte di alcune funzioni.} + \caption{Uso dei collegamenti simbolici da parte di alcune funzioni.} \label{tab:file_symb_effect} \end{table} \footnotetext{a partire dalla serie 2.0, e contrariamente a quanto indicato - dallo standard POSIX, si veda quanto detto in sez.~\ref{sec:file_link}.} + dallo standard POSIX.1-2001.} Si noti che non si è specificato il comportamento delle funzioni che operano con i file descriptor, in quanto la risoluzione del link simbolico viene in @@ -1708,103 +1544,349 @@ genere effettuata dalla funzione che restituisce il file descriptor operazioni seguenti fanno riferimento solo a quest'ultimo. Dato che, come indicato in tab.~\ref{tab:file_symb_effect}, funzioni come la -\func{open} seguono i link simbolici, occorrono funzioni apposite per accedere -alle informazioni del link invece che a quelle del file a cui esso fa -riferimento. Quando si vuole leggere il contenuto di un link simbolico si usa -la funzione \funcd{readlink}, il cui prototipo è: -\begin{prototype}{unistd.h} -{int readlink(const char *path, char *buff, size\_t size)} - Legge il contenuto del link simbolico indicato da \param{path} nel buffer - \param{buff} di dimensione \param{size}. - - \bodydesc{La funzione restituisce il numero di caratteri letti dentro - \param{buff} o -1 per un errore, nel qual caso la variabile - \var{errno} assumerà i valori: +\func{open} seguono i collegamenti simbolici, occorrono funzioni apposite per +accedere alle informazioni del collegamento invece che a quelle del file a cui +esso fa riferimento. Quando si vuole leggere il contenuto di un collegamento +simbolico si usa la funzione di sistema \funcd{readlink}, il cui prototipo è: + +\begin{funcproto}{ +\fhead{unistd.h} +\fdecl{int readlink(const char *path, char *buff, size\_t size)} +\fdesc{Legge il contenuto di un collegamento simbolico.} +} +{La funzione ritorna il numero di caratteri letti dentro \param{buff} in caso + di successo e $-1$ per un errore, nel qual caso \var{errno} assumerà uno + dei valori: \begin{errlist} \item[\errcode{EINVAL}] \param{path} non è un link simbolico o \param{size} non è positiva. - \end{errlist} - ed inoltre \errval{ENOTDIR}, \errval{ENAMETOOLONG}, \errval{ENOENT}, - \errval{EACCES}, \errval{ELOOP}, \errval{EIO}, \errval{EFAULT} e - \errval{ENOMEM}.} -\end{prototype} + \end{errlist} ed inoltre \errval{EACCES}, \errval{EFAULT}, \errval{EIO}, + \errval{ELOOP}, \errval{ENAMETOOLONG}, \errval{ENOENT}, \errval{ENOMEM} e + \errval{ENOTDIR} nel loro significato generico.} +\end{funcproto} -La funzione apre il link simbolico, ne legge il contenuto, lo scrive nel -buffer, e lo richiude. Si tenga presente che la funzione non termina la -stringa con un carattere nullo e la tronca alla dimensione specificata da -\param{size} per evitare di sovrascrivere oltre le dimensioni del buffer. +La funzione legge il \textit{pathname} a cui fa riferimento il collegamento +simbolico indicato dall'argomento \param{path} scrivendolo sul +buffer \param{buff} di dimensione \param{size}. Si tenga presente che la +funzione non termina la stringa con un carattere nullo e che se questa è +troppo lunga la tronca alla dimensione specificata da \param{size} per evitare +di sovrascrivere oltre le dimensioni del buffer. \begin{figure}[htb] \centering \includegraphics[width=8.5cm]{img/link_loop} - \caption{Esempio di loop nel filesystem creato con un link simbolico.} + \caption{Esempio di loop nel filesystem creato con un collegamento + simbolico.} \label{fig:file_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 -fig.~\ref{fig:file_link_loop}, 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{il loop mostrato in - fig.~\ref{fig:file_link_loop} è un usato per poter permettere a \cmd{grub} - (un bootloader in grado di leggere direttamente da vari filesystem il file - da lanciare come sistema operativo) di vedere i file contenuti nella - directory \file{/boot} con lo stesso \textit{pathname} con cui verrebbero - visti dal sistema operativo, anche se essi si trovano, come accade spesso, - su una partizione separata (che \cmd{grub}, all'avvio, vede come radice).} +Come accennato uno dei motivi per cui non sono consentiti \textit{hard link} +alle directory è che questi possono creare dei \textit{loop} nella risoluzione +dei nomi che non possono essere eliminati facilmente. Invece è sempre +possibile, ed in genere anche molto utile, creare un collegamento simbolico ad +una directory, anche se in questo caso si potranno ottenere anche dei +\textit{loop}. La situazione è illustrata in fig.~\ref{fig:file_link_loop}, +che riporta la struttura della directory \file{/boot}. Come si vede si è +creato al suo interno un collegamento simbolico che punta di nuovo a +\file{/boot}.\footnote{il loop mostrato in fig.~\ref{fig:file_link_loop} è un + usato per poter permettere a \cmd{grub} (un bootloader in grado di leggere + direttamente da vari filesystem il file da lanciare come sistema operativo) + di vedere i file contenuti nella directory \file{/boot} con lo stesso + \textit{pathname} con cui verrebbero visti dal sistema operativo, anche se + essi si trovano, come accade spesso, su una partizione separata (che + \cmd{grub}, all'avvio, vede come radice).} Questo può causare problemi per tutti quei programmi che effettuano la -scansione di una directory senza tener conto dei link simbolici, ad esempio se -lanciassimo un comando del tipo \code{grep -r linux *}, il loop nella -directory porterebbe il comando ad esaminare \file{/boot}, \file{/boot/boot}, -\file{/boot/boot/boot} e così via. +scansione di una directory senza tener conto dei collegamenti simbolici, ad +esempio se lanciassimo un comando del tipo \code{grep -r linux *}, il loop +nella directory porterebbe il comando ad esaminare \file{/boot}, +\file{/boot/boot}, \file{/boot/boot/boot} e così via. Per questo motivo il kernel e le librerie prevedono che nella risoluzione di -un \textit{pathname} possano essere seguiti un numero limitato di link +un \textit{pathname} possano essere seguiti un numero limitato di collegamenti simbolici, il cui valore limite è specificato dalla costante \const{MAXSYMLINKS}. Qualora questo limite venga superato viene generato un -errore ed \var{errno} viene impostata al valore \errcode{ELOOP}. +errore ed \var{errno} viene impostata al valore \errcode{ELOOP}, che nella +quasi totalità dei casi indica appunto che si è creato un collegamento +simbolico che fa riferimento ad una directory del suo stesso +\textit{pathname}. + +Un altro punto da tenere sempre presente è che, come abbiamo accennato, un +collegamento simbolico può fare riferimento anche ad un file che non esiste; +ad esempio possiamo usare il comando \cmd{ln} per creare un collegamento +simbolico nella nostra directory con: +\begin{Command} +$ ln -s /tmp/tmp_file symlink +\end{Command} +%$ +e questo avrà successo anche se \file{/tmp/tmp\_file} non esiste: +\begin{Command} +$ ls symlink +\end{Command} +\begin{Terminal} +symlink +\end{Terminal} +%$ +ma questo può generare confusione, perché accedendo in sola lettura a +\file{symlink}, ad esempio con \cmd{cat}, otterremmo un errore: +\begin{Command} +$ cat symlink +\end{Command} +\begin{Terminal} +cat: symlink: No such file or directory +\end{Terminal} +%$ +con un errore che può sembrare sbagliato, dato che \cmd{ls} ci ha mostrato +l'esistenza di \file{symlink}, mentre se invece scrivessimo su \file{symlink} +otterremmo semplicemente la creazione di \file{/tmp/tmp\_file}. + + +\itindend{symbolic~link} +\index{collegamento!simbolico|)} + + + +Un'altra funzione relativa alla gestione dei nomi dei file, anche se a prima +vista parrebbe fare riferimento ad un argomento completamente diverso, è +quella che consente la cancellazione di un file. Il punto è che in realtà una +funzione che serva proprio a cancellare un file non esiste neanche, perché +come accennato in sez.~\ref{sec:file_filesystem}, quando in un sistema +unix-like si richiede la rimozione di un file quello che si va a cancellare è +soltanto la voce che referenzia il suo \textit{inode} all'interno di una +directory. -Un punto da tenere sempre presente è che, come abbiamo accennato, un link -simbolico può fare riferimento 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}%$ -anche se \file{/tmp/tmp\_file} non esiste. Questo può generare confusione, in -quanto aprendo in scrittura \file{temporaneo} verrà creato -\file{/tmp/tmp\_file} e scritto; ma accedendo in sola lettura a -\file{temporaneo}, ad esempio con \cmd{cat}, otterremmo: -\begin{verbatim} -$ cat temporaneo -cat: temporaneo: No such file or directory -\end{verbatim}%$ -con un errore che può sembrare sbagliato, dato che un'ispezione con \cmd{ls} -ci mostrerebbe invece l'esistenza di \file{temporaneo}. +La funzione di sistema che consente di effettuare questa operazione, il cui +nome come si può notare ha poco a che fare con il concetto di rimozione, è +\funcd{unlink}, ed il suo prototipo è: + +\begin{funcproto}{ +\fhead{unistd.h} +\fdecl{int unlink(const char *pathname)} +\fdesc{Cancella un file.} +} +{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, + nel qual caso \var{errno} assumerà uno dei valori: + \begin{errlist} + \item[\errcode{EISDIR}] \param{pathname} si riferisce ad una + directory.\footnotemark + \item[\errcode{EROFS}] \param{pathname} è su un filesystem montato in sola + lettura. + \item[\errcode{EISDIR}] \param{pathname} fa riferimento a una directory. + \end{errlist} ed inoltre \errval{EACCES}, \errval{EFAULT}, \errval{ENOENT}, + \errval{ENOTDIR}, \errval{ENOMEM}, \errval{EROFS}, \errval{ELOOP}, + \errval{EIO} nel loro significato generico.} +\end{funcproto} + +\footnotetext{questo è un valore specifico ritornato da Linux che non consente + l'uso di \func{unlink} con le directory. Non è conforme allo standard + POSIX, che prescrive invece l'uso di \errcode{EPERM} in caso l'operazione + non sia consentita o il processo non abbia privilegi sufficienti.} + +La funzione elimina il nome specificato dall'argomento \param{pathname} nella +directory che lo contiene e decrementa il numero di riferimenti nel relativo +\itindex{inode} \textit{inode}. Nel caso di socket, fifo o file di dispositivo +\index{file!di~dispositivo} rimuove il nome, ma come per i file normali i +processi che hanno aperto uno di questi oggetti possono continuare ad +utilizzarli. Solo nel caso di cancellazione di un collegamento simbolico, che +consiste solo nel rimando ad un altro file, questo viene immediatamente +eliminato. + +Per cancellare una voce in una directory è necessario avere il permesso di +scrittura su di essa, dato che si va a rimuovere una voce dal suo contenuto, e +il diritto di esecuzione sulla directory che la contiene (affronteremo in +dettaglio l'argomento dei permessi di file e directory in +sez.~\ref{sec:file_access_control}). Se inoltre lo \itindex{sticky~bit} +\textit{sticky bit} (vedi sez.~\ref{sec:file_special_perm}) è impostato +occorrerà anche essere proprietari del file o proprietari della directory o +avere i privilegi di amministratore. + +Una delle caratteristiche comuni fra \func{link} ed \func{unlink} è che la +creazione/rimozione del nome dalla directory e l'incremento/decremento del +numero di riferimenti \itindex{inode} nell'\textit{inode} sono sempre +effettuati in maniera atomica (si veda sez.~\ref{sec:proc_atom_oper}) senza +possibili interruzioni fra le due operazioni, questo entrambe queste funzioni +sono realizzate tramite una \textit{system call}. + +Si ricordi inoltre che anche se ne è rimosso il nome da una directory un file +non viene eliminato dal disco fintanto che tutti i riferimenti ad esso sono +stati cancellati: solo quando il numero di collegamenti mantenuto +\itindex{inode} nell'\textit{inode} diventa nullo, questo viene disallocato lo +spazio occupato su disco viene liberato. Si tenga presente comunque che a +questo si aggiunge sempre un'ulteriore condizione e cioè che non ci siano +processi che abbiano il suddetto file aperto.\footnote{come vedremo in + cap.~\ref{cha:file_unix_interface} il kernel mantiene anche una tabella dei + file aperti nei vari processi, che a sua volta contiene i riferimenti agli + \itindex{inode} \textit{inode} ad essi relativi; prima di procedere alla + cancellazione dello spazio occupato su disco dal contenuto di un file il + kernel controlla anche questa tabella, per verificare che anche in essa non + ci sia più nessun riferimento all'\textit{inode} in questione.} + +Questa caratteristica del sistema viene spesso usata per essere sicuri di non +lasciare file temporanei su disco in caso di crash dei programmi. La tecnica è +quella di creare un nuovo file e chiamare \func{unlink} subito dopo, in questo +modo il contenuto del file sarà sempre disponibile all'interno del processo +attraverso il suo file descriptor (vedi sez.~\ref{sec:file_fd}) fintanto che +il processo non chiude il file, ma non ne resta traccia in nessuna directory, +e lo spazio occupato su disco viene immediatamente rilasciato alla conclusione +del processo (quando tutti i file vengono chiusi). + +Al contrario di quanto avviene con altri Unix, in Linux non è possibile usare +la funzione \func{unlink} sulle directory, per le quali si otterrebbe un +errore di \errcode{EISDIR}. Per cancellare una directory si può usare la +apposita funzione di sistema \func{rmdir} (che vedremo in +sez.~\ref{sec:file_dir_creat_rem}), oppure la funzione \func{remove}. +Quest'ultima è la funzione prevista dallo standard ANSI C per effeettuare una +cancellazione generica di un file o di una directory e funziona anche per i +sistemi operativo che non supportano gli \textit{hard link}. Nei sistemi +unix-like \funcd{remove} è equivalente ad usare in maniera trasparente +\func{unlink} per i file ed \func{rmdir} per le directory; il suo prototipo è: + +\begin{funcproto}{ +\fhead{stdio.h} +\fdecl{int remove(const char *pathname)} +\fdesc{Cancella un file o una directory.} +} +{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual + caso \var{errno} assumerà uno dei valori relativi alla chiamata utilizzata, + pertanto si può fare riferimento a quanto illustrato nelle descrizioni di + \func{unlink} e \func{rmdir}.} +\end{funcproto} + +La funzione utilizza la funzione \func{unlink} per cancellare i file e la +funzione \func{rmdir} (vedi sez.~\ref{sec:file_dir_creat_rem}) per cancellare +le directory.\footnote{questo vale usando la \acr{glibc}; nella libc4 e nella + libc5 la funzione \func{remove} era un semplice alias alla funzione + \func{unlink} e quindi non poteva essere usata per le directory.} Si tenga +presente che per alcune implementazioni del protocollo NFS utilizzare questa +funzione può comportare la scomparsa di file ancora in uso. + +Infine per cambiare nome ad un file o a una directory si usa la funzione di +sistema \funcd{rename},\footnote{la funzione è definita dallo standard ANSI C, + ma si applica solo per i file, lo standard POSIX estende la funzione anche + alle directory.} il cui prototipo è: + +\begin{funcproto}{ +\fhead{stdio.h} +\fdecl{int rename(const char *oldpath, const char *newpath)} +\fdesc{Rinomina un file o una directory.} +} +{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, + nel qual caso \var{errno} assumerà uno dei valori: + \begin{errlist} + \item[\errcode{EACCESS}] non c'è permesso di scrivere nelle directory + contenenti \param{oldpath} e \param{newpath} o di attraversare + quelle dei loro \textit{pathname} o di scrivere su \param{newpath} + se questa è una directory. + \item[\errcode{EBUSY}] o \param{oldpath} o \param{newpath} sono in uso da + parte di qualche processo (come \index{directory~di~lavoro} directory di + lavoro o come radice) o del sistema (come \itindex{mount~point} + \textit{mount point}) ed il sistema non riesce a risolvere la situazione. + \item[\errcode{EINVAL}] \param{newpath} contiene un prefisso di + \param{oldpath} o più in generale si è cercato di creare una directory come + sotto-directory di sé stessa. + \item[\errcode{EISDIR}] \param{newpath} è una directory mentre + \param{oldpath} non è una directory. + \item[\errcode{EEXIST}] \param{newpath} è una directory già esistente e + non è vuota (anche \errcode{ENOTEMPTY}). + \item[\errcode{ENOTDIR}] uno dei componenti dei \textit{pathname} non è una + directory o \param{oldpath} è una directory e + \param{newpath} esiste e non è una directory. + \item[\errval{EPERM}] la directory contenente \param{oldpath} o quella + contenente un \param{newpath} esistente hanno lo + \itindex{sticky~bit} \textit{sticky bit} e non si è i proprietari dei + rispettivi file (o non si hanno privilegi amministrativi) oppure il + filesystem non supporta l'operazione. + \item[\errcode{EXDEV}] \param{oldpath} e \param{newpath} non sono sullo + stesso filesystem e sotto lo stesso \itindex{mount~point} \textit{mount + point}. + \end{errlist} ed inoltre \errval{EFAULT}, \errval{ELOOP}, \errval{EMLINK}, + \errval{ENAMETOOLONG}, \errval{ENOENT}, \errval{ENOMEM}, \errval{ENOSPC} e + \errval{EROFS} nel loro significato generico.} +\end{funcproto} + +La funzione rinomina in \param{newpath} il file o la directory indicati +dall'argomento \param{oldpath}. Il nome viene eliminato nella directory +originale e ricreato nella directory di destinazione mantenendo il riferimento +allo stesso \itindex{inode} \textit{inode}. Non viene spostato nessun dato e +\itindex{inode} l'\textit{inode} del file non subisce nessuna modifica in +quanto le modifiche sono eseguite sulle directory che +contengono \param{newpath} ed \param{oldpath}. + +Il vantaggio nell'uso di questa funzione al posto della chiamata successiva di +\func{link} e \func{unlink} è che l'operazione è eseguita atomicamente, non +c'è modifica, per quanto temporanea, al \textit{link count} del file e non può +esistere cioè nessun istante in cui un altro processo possa trovare attivi +entrambi i nomi dello stesso file (a parte il caso di sovrascrittura), o, in +caso di sostituzione di un file esistente, non trovare quest'ultimo prima che +la sostituzione sia stata eseguita. + +Dato che opera in maniera analoga la funzione è soggetta alle stesse +restrizioni di \func{link}, quindi è necessario che \param{oldpath} +e \param{newpath} siano nello stesso filesystem e facciano riferimento allo +stesso \itindex{mount~point} \textit{mount point}, e che il filesystem +supporti questo tipo di operazione. Qualora questo non avvenga si dovrà +effettuare l'operazione in maniera non atomica copiando il file a destinazione +e poi cancellando l'orginale. + +Il comportamento della funzione è diverso a seconda che si voglia rinominare +un file o una directory. Se ci riferisce ad un file allora \param{newpath}, se +esiste, non deve essere una directory, altrimenti si avrà un errore di +\errcode{EISDIR}. Se \param{newpath} indica un file già esistente questo verrà +rimpiazzato atomicamente, ma nel caso in cui \func{rename} fallisca esso non +sarà toccato. I caso di sovrascrittura esisterà però una breve finestra di +tempo in cui sia \param{oldpath} che \param{newpath} potranno fare entrambi +riferimento al file che viene rinominato. + +Se \param{oldpath} è una directory allora \param{newpath}, se esistente, deve +essere una directory vuota, altrimenti si avranno gli errori \errcode{ENOTDIR} +(se non è una directory) o \errcode{ENOTEMPTY} o \errcode{EEXIST} (se non è +vuota). Chiaramente \param{newpath} non potrà contenere \param{oldpath} nel +suo \textit{pathname}, non essendo possibile rendere una directory +sottodirectory di sé stessa, nel qual caso si avrà un errore di +\errcode{EINVAL}. + +Se \param{oldpath} si riferisce ad un collegamento simbolico questo sarà +rinominato restando tale senza nessun effetto sul file a cui fa riferimento. +Se invece \param{newpath} esiste ed è un collegamento simbolico verrà +cancellato come qualunque altro file. Infine qualora \param{oldpath} +e \param{newpath} siano due nomi che già fanno riferimento allo stesso file lo +standard POSIX prevede che la funzione non ritorni un errore, e semplicemente +non faccia nulla, lasciando entrambi i nomi. Linux segue questo standard, +anche se, come fatto notare dal manuale della \acr{glibc}, il comportamento +più ragionevole sarebbe quello di cancellare \param{oldpath}. + +In tutti i casi si dovranno avere i permessi di scrittura nelle directory +contenenti \param{oldpath} e \param{newpath}, e nel caso \param{newpath} sia +una directory vuota già esistente anche su di essa (perché dovrà essere +aggiornata la voce ``\texttt{..}''). Se poi le directory +contenenti \param{oldpath} o \param{newpath} hanno lo \itindex{sticky~bit} +\textit{sticky bit} attivo (vedi sez.~\ref{sec:file_special_perm}) si dovrà +essere i proprietari dei file (o delle directory) che si vogliono rinominare, +o avere i permessi di amministratore. \subsection{La creazione e la cancellazione delle directory} \label{sec:file_dir_creat_rem} Benché in sostanza le directory non siano altro che dei file contenenti -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, 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 è +elenchi di nomi con riferimenti ai rispettivi \itindex{inode} \textit{inode}, +non è possibile trattarle come file ordinari e devono essere create +direttamente dal kernel attraverso una opportuna \textit{system + call}.\footnote{questo è quello che permette anche, attraverso l'uso del + VFS, l'utilizzo di diversi formati per la gestione dei 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 di sistema usata per creare una directory è \funcd{mkdir}, ed il suo prototipo è: -\begin{functions} - \headdecl{sys/stat.h} - \headdecl{sys/types.h} - \funcdecl{int mkdir(const char *dirname, mode\_t mode)} - Crea una nuova directory. - - \bodydesc{La funzione restituisce zero in caso di successo e -1 per un - errore, nel qual caso \var{errno} assumerà i valori: +\begin{funcproto}{ +\fhead{sys/stat.h} +\fhead{sys/types.h} +\fdecl{int mkdir(const char *dirname, mode\_t mode)} +\fdesc{Crea una nuova directory.} +} +{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual + caso \var{errno} assumerà uno dei valori: \begin{errlist} \item[\errcode{EEXIST}] un file (o una directory) con quel nome esiste di già. @@ -1819,226 +1901,65 @@ una opportuna system call.\footnote{questo è quello che permette anche, \item[\errcode{ENOSPC}] non c'è abbastanza spazio sul file system per creare la nuova directory o si è esaurita la quota disco dell'utente. \end{errlist} - ed inoltre anche \errval{EPERM}, \errval{EFAULT}, \errval{ENAMETOOLONG}, - \errval{ENOENT}, \errval{ENOTDIR}, \errval{ENOMEM}, \errval{ELOOP}, - \errval{EROFS}.} -\end{functions} - -La funzione crea una nuova directory vuota, che contiene cioè solo le due voci -standard presenti in ogni directory (cioè ``\file{.}'' e ``\file{..}''), con -il nome indicato dall'argomento \param{dirname}. Il nome può essere indicato -sia come \itindsub{pathname}{assoluto} \textit{pathname} assoluto che come -\itindsub{pathname}{relativo} \textit{pathname} relativo. - -I permessi di accesso (vedi sez.~\ref{sec:file_access_control}) con cui la -directory viene creata sono specificati dall'argomento \param{mode}, i cui -possibili valori sono riportati in tab.~\ref{tab:file_permission_const}; si -tenga presente che questi sono modificati dalla maschera di creazione dei file -(si veda sez.~\ref{sec:file_perm_management}). La titolarità della nuova -directory è impostata secondo quanto riportato in -sez.~\ref{sec:file_ownership_management}. - -La funzione che permette la cancellazione di una directory è invece -\funcd{rmdir}, ed il suo prototipo è: -\begin{prototype}{sys/stat.h}{int rmdir(const char *dirname)} - Cancella una directory. - - \bodydesc{La funzione restituisce zero in caso di successo e -1 per un - errore, nel qual caso \var{errno} assumerà i valori: - \begin{errlist} - \item[\errcode{EPERM}] il filesystem non supporta la cancellazione di - directory, oppure la directory che contiene \param{dirname} ha lo - \itindex{sticky~bit} \textit{sticky bit} impostato e l'\ids{UID} effettivo - del processo non corrisponde al proprietario della directory. - \item[\errcode{EACCES}] non c'è il permesso di scrittura per la directory - che contiene la directory che si vuole cancellare, o non c'è il permesso - di attraversare (esecuzione) una delle directory specificate in - \param{dirname}. - \item[\errcode{EBUSY}] la directory specificata è la - \index{directory~di~lavoro} directory di lavoro o la radice di qualche - processo. - \item[\errcode{ENOTEMPTY}] la directory non è vuota. - \end{errlist} - ed inoltre anche \errval{EFAULT}, \errval{ENAMETOOLONG}, \errval{ENOENT}, - \errval{ENOTDIR}, \errval{ENOMEM}, \errval{ELOOP}, \errval{EROFS}.} -\end{prototype} - -La funzione cancella la directory \param{dirname}, che deve essere vuota (la -directory deve cioè contenere soltanto le due voci standard ``\file{.}'' e -``\file{..}''). Il nome può essere indicato con il \textit{pathname} assoluto -o relativo. - -La modalità con cui avviene la cancellazione è analoga a quella di -\func{unlink}: fintanto che il numero di link \itindex{inode} -all'\textit{inode} della directory non diventa nullo e nessun processo ha la -directory aperta lo spazio occupato su disco non viene rilasciato. Se un -processo ha la directory aperta la funzione rimuove il link \itindex{inode} -all'\textit{inode} e nel caso sia l'ultimo, pure le voci standard ``\file{.}'' -e ``\file{..}'', a questo punto il kernel non consentirà di creare più nuovi -file nella directory. - - -\subsection{La creazione di file speciali} -\label{sec:file_mknod} - -\index{file!di~dispositivo|(} - -Finora abbiamo parlato esclusivamente di file, directory e link simbolici; in -sez.~\ref{sec:file_file_types} abbiamo visto però che il sistema prevede pure -degli altri tipi di file speciali, come i file di dispositivo, le fifo ed i -socket (questi ultimi sono un caso a parte, essendo associati anche alla -comunicazione via rete, per cui ci saranno trattati in dettaglio a partire da -cap.~\ref{cha:socket_intro}). - -La manipolazione delle caratteristiche di questi diversi tipi di file e la -loro cancellazione può essere effettuata con le stesse funzioni che operano -sui file regolari; ma quando li si devono creare sono necessarie delle -funzioni apposite. La prima di queste funzioni è \funcd{mknod}, il cui -prototipo è: -\begin{functions} - \headdecl{sys/types.h} - \headdecl{sys/stat.h} - \headdecl{fcntl.h} - \headdecl{unistd.h} - \funcdecl{int mknod(const char *pathname, mode\_t mode, dev\_t dev)} - - Crea un \textit{inode} del tipo specificato sul filesystem. - - \bodydesc{La funzione restituisce zero in caso di successo e -1 per un - errore, nel qual caso \var{errno} assumerà i valori: - \begin{errlist} - \item[\errcode{EPERM}] non si hanno privilegi sufficienti a creare - l'\texttt{inode}, o il filesystem su cui si è cercato di - creare \param{pathname} non supporta l'operazione. - \item[\errcode{EINVAL}] il valore di \param{mode} non indica un file, una - fifo, un socket o un dispositivo. - \item[\errcode{EEXIST}] \param{pathname} esiste già o è un link simbolico. - \end{errlist} - ed inoltre anche \errval{EFAULT}, \errval{EACCES}, \errval{ENAMETOOLONG}, - \errval{ENOENT}, \errval{ENOTDIR}, \errval{ENOMEM}, \errval{ELOOP}, - \errval{ENOSPC}, \errval{EROFS}.} -\end{functions} - -La funzione, come suggerisce il nome, permette di creare un ``\textsl{nodo}'' -sul filesystem, e viene in genere utilizzata per creare i file di dispositivo, -ma si può usare anche per creare file regolari. L'argomento -\param{mode} specifica sia il tipo di file che si vuole creare che i relativi -permessi, secondo i valori riportati in tab.~\ref{tab:file_mode_flags}, che -vanno combinati con un OR binario. I permessi sono comunque modificati nella -maniera usuale dal valore di \itindex{umask} \textit{umask} (si veda -sez.~\ref{sec:file_perm_management}). - -Per il tipo di file può essere specificato solo uno fra i seguenti valori: -\const{S\_IFREG} per un file regolare (che sarà creato vuoto), -\const{S\_IFBLK} per un dispositivo a blocchi, \const{S\_IFCHR} per un -dispositivo a caratteri, \const{S\_IFSOCK} per un socket e \const{S\_IFIFO} -per una fifo;\footnote{con Linux la funzione non può essere usata per creare - directory o link simbolici, si dovranno usare le funzioni \func{mkdir} e - \func{symlink} a questo dedicate.} un valore diverso comporterà l'errore -\errcode{EINVAL}. - -Qualora si sia specificato in \param{mode} un file di dispositivo (vale a dire -o \const{S\_IFBLK} o \const{S\_IFCHR}), il valore di \param{dev} dovrà essere -usato per indicare a quale dispositivo si fa riferimento, altrimenti il suo -valore verrà ignorato. Solo l'amministratore può creare un file di -dispositivo usando questa funzione (il processo deve avere la -\itindex{capabilities} \textit{capability} \const{CAP\_MKNOD}), ma in -Linux\footnote{questo è un comportamento specifico di Linux, la funzione non è - prevista dallo standard POSIX.1 originale, mentre è presente in SVr4 e - 4.4BSD, ma esistono differenze nei comportamenti e nei codici di errore, - tanto che questa è stata introdotta in POSIX.1-2001 con una nota che la - definisce portabile solo quando viene usata per creare delle fifo, ma - comunque deprecata essendo utilizzabile a tale scopo la specifica - \func{mkfifo}.} l'uso per la creazione di un file ordinario, di una fifo o -di un socket è consentito anche agli utenti normali. - -I nuovi \itindex{inode} \textit{inode} creati con \func{mknod} apparterranno -al proprietario e al gruppo del processo che li ha creati, a meno che non si -sia attivato il bit \acr{sgid} per la directory o sia stata attivata la -semantica BSD per il filesystem (si veda -sez.~\ref{sec:file_ownership_management}) in cui si va a creare -\itindex{inode} l'\textit{inode}. - -Nella creazione di un file di dispositivo occorre poi specificare -correttamente il valore di \param{dev}; questo infatti è di tipo -\type{dev\_t}, che è un tipo primitivo (vedi -tab.~\ref{tab:intro_primitive_types}) riservato per indicare un -\textsl{numero} di dispositivo; il kernel infatti identifica ciascun -dispositivo con un valore numerico. Originariamente questo era un intero a 16 -bit diviso in due parti di 8 bit chiamate rispettivamente -\itindex{major~number} \textit{major number} e \itindex{minor~number} -\textit{minor number}, che sono poi i due numeri mostrati dal comando -\texttt{ls -l} al posto della dimensione quando lo si esegue su un file di -dispositivo. - -Il \itindex{major~number} \textit{major number} identifica una classe di -dispositivi (ad esempio la seriale, o i dischi IDE) e serve in sostanza per -indicare al kernel quale è il modulo che gestisce quella classe di -dispositivi; per identificare uno specifico dispositivo di quella classe (ad -esempio una singola porta seriale, o una partizione di un disco) si usa invece -il \itindex{minor~number} \textit{minor number}. L'elenco aggiornato di questi -numeri con le relative corrispondenze ai vari dispositivi può essere trovato -nel file \texttt{Documentation/devices.txt} allegato alla documentazione dei -sorgenti del kernel. - -Data la crescita nel numero di dispositivi supportati, ben presto il limite -massimo di 256 si è rivelato troppo basso, e nel passaggio dai kernel della -serie 2.4 alla serie 2.6 è stata aumentata a 32 bit la dimensione del tipo -\type{dev\_t}, con delle dimensioni passate a 12 bit per il -\itindex{major~number} \textit{major number} e 20 bit per il -\itindex{minor~number} \textit{minor number}. La transizione però ha anche -comportato il passaggio di \type{dev\_t} a \index{tipo!opaco} tipo opaco, e la -necessità di specificare il numero tramite delle opportune macro, così da non -avere problemi di compatibilità con eventuali ulteriori estensioni. + ed inoltre \errval{EPERM}, \errval{EFAULT}, \errval{ENAMETOOLONG}, + \errval{ENOENT}, \errval{ENOTDIR}, \errval{ENOMEM}, \errval{ELOOP}, + \errval{EROFS} nel loro significato generico.} +\end{funcproto} -Le macro sono definite nel file \headfile{sys/sysmacros.h}, che viene -automaticamente incluso quando si include \headfile{sys/types.h}; si possono -pertanto ottenere i valori del \itindex{major~number} \textit{major number} e -\itindex{minor~number} \textit{minor number} di un dispositivo rispettivamente -con le macro \macro{major} e \macro{minor}: -\begin{functions} - \headdecl{sys/types.h} - \funcdecl{int \macro{major}(dev\_t dev)} - Restituisce il \itindex{major~number} \textit{major number} del dispositivo - \param{dev}. - - \funcdecl{int \macro{minor}(dev\_t dev)} - Restituisce il \itindex{minor~number} \textit{minor number} del dispositivo - \param{dev}. -\end{functions} -\noindent mentre una volta che siano noti \itindex{major~number} \textit{major - number} e \itindex{minor~number} \textit{minor number} si potrà costruire il -relativo identificativo con la macro \macro{makedev}: -\begin{functions} - \headdecl{sys/types.h} - \funcdecl{dev\_t \macro{minor}(int major, int minor)} - Restituisce l'identificativo di un dispositivo dati \itindex{major~number} - \textit{major number} e \itindex{minor~number} \textit{minor number}. -\end{functions} -\index{file!di~dispositivo|)} +La funzione crea una nuova directory vuota, che contiene cioè solo le due voci +standard presenti in ogni directory (cioè ``\file{.}'' e ``\file{..}''), con +il nome indicato dall'argomento \param{dirname}. Il nome può essere indicato +sia come \itindsub{pathname}{assoluto} \textit{pathname} assoluto che come +\itindsub{pathname}{relativo} \textit{pathname} relativo. + +I permessi di accesso (vedi sez.~\ref{sec:file_access_control}) con cui la +directory viene creata sono specificati dall'argomento \param{mode}, i cui +possibili valori sono riportati in tab.~\ref{tab:file_permission_const}; si +tenga presente che questi sono modificati dalla maschera di creazione dei file +(si veda sez.~\ref{sec:file_perm_management}). La titolarità della nuova +directory è impostata secondo quanto riportato in +sez.~\ref{sec:file_ownership_management}. + +La funzione che permette la cancellazione di una directory è invece +\funcd{rmdir}, ed il suo prototipo è: +\begin{prototype}{sys/stat.h}{int rmdir(const char *dirname)} + Cancella una directory. -Infine con lo standard POSIX.1-2001 è stata introdotta una funzione specifica -per creare una fifo (tratteremo le fifo in in sez.~\ref{sec:ipc_named_pipe}); -la funzione è \funcd{mkfifo} ed il suo prototipo è: -\begin{functions} - \headdecl{sys/types.h} \headdecl{sys/stat.h} - - \funcdecl{int mkfifo(const char *pathname, mode\_t mode)} - - Crea una fifo. - \bodydesc{La funzione restituisce zero in caso di successo e -1 per un - errore, nel qual caso \var{errno} assumerà i valori \errval{EACCES}, - \errval{EEXIST}, \errval{ENAMETOOLONG}, \errval{ENOENT}, \errval{ENOSPC}, - \errval{ENOTDIR} e \errval{EROFS}.} -\end{functions} + errore, nel qual caso \var{errno} assumerà i valori: + \begin{errlist} + \item[\errcode{EPERM}] il filesystem non supporta la cancellazione di + directory, oppure la directory che contiene \param{dirname} ha lo + \itindex{sticky~bit} \textit{sticky bit} impostato e l'\ids{UID} effettivo + del processo non corrisponde al proprietario della directory. + \item[\errcode{EACCES}] non c'è il permesso di scrittura per la directory + che contiene la directory che si vuole cancellare, o non c'è il permesso + di attraversare (esecuzione) una delle directory specificate in + \param{dirname}. + \item[\errcode{EBUSY}] la directory specificata è la + \index{directory~di~lavoro} directory di lavoro o la radice di qualche + processo. + \item[\errcode{ENOTEMPTY}] la directory non è vuota. + \end{errlist} + ed inoltre anche \errval{EFAULT}, \errval{ENAMETOOLONG}, \errval{ENOENT}, + \errval{ENOTDIR}, \errval{ENOMEM}, \errval{ELOOP}, \errval{EROFS}.} +\end{prototype} -La funzione crea la fifo \param{pathname} con i permessi \param{mode}. Come -per \func{mknod} il file \param{pathname} non deve esistere (neanche come link -simbolico); al solito i permessi specificati da \param{mode} vengono -modificati dal valore di \itindex{umask} \textit{umask}. +La funzione cancella la directory \param{dirname}, che deve essere vuota (la +directory deve cioè contenere soltanto le due voci standard ``\file{.}'' e +``\file{..}''). Il nome può essere indicato con il \textit{pathname} assoluto +o relativo. + +La modalità con cui avviene la cancellazione è analoga a quella di +\func{unlink}: fintanto che il numero di collegamenti \itindex{inode} +all'\textit{inode} della directory non diventa nullo e nessun processo ha la +directory aperta lo spazio occupato su disco non viene rilasciato. Se un +processo ha la directory aperta la funzione rimuove il collegamento +\itindex{inode} all'\textit{inode} e nel caso sia l'ultimo, pure le voci +standard ``\file{.}'' e ``\file{..}'', a questo punto il kernel non +consentirà di creare più nuovi file nella directory. @@ -2099,9 +2020,9 @@ 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 + 5.1.2) e con la \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 + della \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 è: @@ -2126,9 +2047,9 @@ 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{fdopendir},\footnote{questa funzione è però disponibile solo a partire - dalla versione 2.4 delle \acr{glibc}, ed è stata introdotta nello standard + dalla versione 2.4 della \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 + della \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 è: @@ -2258,7 +2179,7 @@ definite le macro \macro{\_DIRENT\_HAVE\_D\_TYPE}, \const{DT\_UNKNOWN} & Tipo sconosciuto.\\ \const{DT\_REG} & File normale.\\ \const{DT\_DIR} & Directory.\\ - \const{DT\_LNK} & Link simbolico.\\ + \const{DT\_LNK} & Collegamento simbolico.\\ \const{DT\_FIFO} & Fifo.\\ \const{DT\_SOCK} & Socket.\\ \const{DT\_CHR} & Dispositivo a caratteri.\\ @@ -2271,14 +2192,14 @@ definite le macro \macro{\_DIRENT\_HAVE\_D\_TYPE}, \end{table} Per quanto riguarda il significato dei campi opzionali, il campo \var{d\_type} -indica il tipo di file (se fifo, directory, link simbolico, ecc.), e consente +indica il tipo di file (se fifo, directory, collegamento 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 + della \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}.} @@ -2311,7 +2232,7 @@ 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 è:\footnote{prima - delle \acr{glibc} 2.1.1 la funzione restituiva un valore di tipo + della \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)} @@ -2410,16 +2331,16 @@ Per l'ordinamento, vale a dire come valori possibili per l'argomento La funzione \func{alphasort} deriva da BSD ed è presente in Linux fin dalle \acr{libc4}\footnote{la versione delle \acr{libc4} e \acr{libc5} usa però come - argomenti dei puntatori a delle strutture \struct{dirent}; le glibc usano il + argomenti dei puntatori a delle strutture \struct{dirent}; la glibc usa il prototipo originario di BSD, mostrato anche nella definizione, che prevede puntatori a \ctyp{void}.} e deve essere specificata come argomento \param{compar} per ottenere un ordinamento alfabetico (secondo il valore del -campo \var{d\_name} delle varie voci). Le \acr{glibc} prevedono come -estensione\footnote{le glibc, a partire dalla versione 2.1, effettuano anche - l'ordinamento alfabetico tenendo conto delle varie localizzazioni, usando - \funcm{strcoll} al posto di \funcm{strcmp}.} anche \func{versionsort}, che -ordina i nomi tenendo conto del numero di versione (cioè qualcosa per cui -\texttt{file10} viene comunque dopo \texttt{file4}.) +campo \var{d\_name} delle varie voci). La \acr{glibc} prevede come +estensione\footnote{la \acr{glibc}, a partire dalla versione 2.1, effettua + anche l'ordinamento alfabetico tenendo conto delle varie localizzazioni, + usando \funcm{strcoll} al posto di \funcm{strcmp}.} anche +\func{versionsort}, che ordina i nomi tenendo conto del numero di versione +(cioè qualcosa per cui \texttt{file10} viene comunque dopo \texttt{file4}.) \begin{figure}[!htbp] \footnotesize \centering @@ -2587,14 +2508,14 @@ più veloce, se non si è a corto di file descriptor, è invece quello di aprire la directory corrente (vale a dire ``\texttt{.}'') e tornarvi in seguito con \func{fchdir}. -Una seconda usata per ottenere la directory di lavoro è \code{char +Una seconda funzione usata per ottenere la directory di lavoro è \code{char *get\_current\_dir\_name(void)} che è sostanzialmente equivalente ad una \code{getcwd(NULL, 0)}, con la sola differenza che essa ritorna il valore della variabile di ambiente \envvar{PWD}, che essendo costruita dalla shell -può contenere un \textit{pathname} comprendente anche dei link +può contenere un \textit{pathname} comprendente anche dei collegamenti simbolici. Usando \func{getcwd} infatti, essendo il \textit{pathname} ricavato risalendo all'indietro l'albero della directory, si perderebbe traccia di ogni -passaggio attraverso eventuali link simbolici. +passaggio attraverso eventuali collegamenti simbolici. Per cambiare la directory di lavoro si può usare la funzione \funcd{chdir} (equivalente del comando di shell \cmd{cd}) il cui nome sta appunto per @@ -2635,6 +2556,169 @@ specificata da \param{fd}. \index{directory~di~lavoro|)} +\subsection{La creazione di file speciali} +\label{sec:file_mknod} + +\index{file!di~dispositivo|(} + +Finora abbiamo parlato esclusivamente di file, directory e link simbolici; in +sez.~\ref{sec:file_file_types} abbiamo visto però che il sistema prevede pure +degli altri tipi di file speciali, come i file di dispositivo, le fifo ed i +socket (questi ultimi sono un caso a parte, essendo associati anche alla +comunicazione via rete, per cui ci saranno trattati in dettaglio a partire da +cap.~\ref{cha:socket_intro}). + +La manipolazione delle caratteristiche di questi diversi tipi di file e la +loro cancellazione può essere effettuata con le stesse funzioni che operano +sui file regolari; ma quando li si devono creare sono necessarie delle +funzioni apposite. La prima di queste funzioni è \funcd{mknod}, il cui +prototipo è: +\begin{functions} + \headdecl{sys/types.h} + \headdecl{sys/stat.h} + \headdecl{fcntl.h} + \headdecl{unistd.h} + \funcdecl{int mknod(const char *pathname, mode\_t mode, dev\_t dev)} + + Crea un \textit{inode} del tipo specificato sul filesystem. + + \bodydesc{La funzione restituisce zero in caso di successo e -1 per un + errore, nel qual caso \var{errno} assumerà i valori: + \begin{errlist} + \item[\errcode{EPERM}] non si hanno privilegi sufficienti a creare + l'\texttt{inode}, o il filesystem su cui si è cercato di + creare \param{pathname} non supporta l'operazione. + \item[\errcode{EINVAL}] il valore di \param{mode} non indica un file, una + fifo, un socket o un dispositivo. + \item[\errcode{EEXIST}] \param{pathname} esiste già o è un link simbolico. + \end{errlist} + ed inoltre anche \errval{EFAULT}, \errval{EACCES}, \errval{ENAMETOOLONG}, + \errval{ENOENT}, \errval{ENOTDIR}, \errval{ENOMEM}, \errval{ELOOP}, + \errval{ENOSPC}, \errval{EROFS}.} +\end{functions} + +La funzione, come suggerisce il nome, permette di creare un ``\textsl{nodo}'' +sul filesystem, e viene in genere utilizzata per creare i file di dispositivo, +ma si può usare anche per creare file regolari. L'argomento +\param{mode} specifica sia il tipo di file che si vuole creare che i relativi +permessi, secondo i valori riportati in tab.~\ref{tab:file_mode_flags}, che +vanno combinati con un OR binario. I permessi sono comunque modificati nella +maniera usuale dal valore di \itindex{umask} \textit{umask} (si veda +sez.~\ref{sec:file_perm_management}). + +Per il tipo di file può essere specificato solo uno fra i seguenti valori: +\const{S\_IFREG} per un file regolare (che sarà creato vuoto), +\const{S\_IFBLK} per un dispositivo a blocchi, \const{S\_IFCHR} per un +dispositivo a caratteri, \const{S\_IFSOCK} per un socket e \const{S\_IFIFO} +per una fifo;\footnote{con Linux la funzione non può essere usata per creare + directory o link simbolici, si dovranno usare le funzioni \func{mkdir} e + \func{symlink} a questo dedicate.} un valore diverso comporterà l'errore +\errcode{EINVAL}. + +Qualora si sia specificato in \param{mode} un file di dispositivo (vale a dire +o \const{S\_IFBLK} o \const{S\_IFCHR}), il valore di \param{dev} dovrà essere +usato per indicare a quale dispositivo si fa riferimento, altrimenti il suo +valore verrà ignorato. Solo l'amministratore può creare un file di +dispositivo usando questa funzione (il processo deve avere la +\itindex{capabilities} \textit{capability} \const{CAP\_MKNOD}), ma in +Linux\footnote{questo è un comportamento specifico di Linux, la funzione non è + prevista dallo standard POSIX.1 originale, mentre è presente in SVr4 e + 4.4BSD, ma esistono differenze nei comportamenti e nei codici di errore, + tanto che questa è stata introdotta in POSIX.1-2001 con una nota che la + definisce portabile solo quando viene usata per creare delle fifo, ma + comunque deprecata essendo utilizzabile a tale scopo la specifica + \func{mkfifo}.} l'uso per la creazione di un file ordinario, di una fifo o +di un socket è consentito anche agli utenti normali. + +I nuovi \itindex{inode} \textit{inode} creati con \func{mknod} apparterranno +al proprietario e al gruppo del processo che li ha creati, a meno che non si +sia attivato il bit \acr{sgid} per la directory o sia stata attivata la +semantica BSD per il filesystem (si veda +sez.~\ref{sec:file_ownership_management}) in cui si va a creare +\itindex{inode} l'\textit{inode}. + +Nella creazione di un file di dispositivo occorre poi specificare +correttamente il valore di \param{dev}; questo infatti è di tipo +\type{dev\_t}, che è un tipo primitivo (vedi +tab.~\ref{tab:intro_primitive_types}) riservato per indicare un +\textsl{numero} di dispositivo; il kernel infatti identifica ciascun +dispositivo con un valore numerico. Originariamente questo era un intero a 16 +bit diviso in due parti di 8 bit chiamate rispettivamente +\itindex{major~number} \textit{major number} e \itindex{minor~number} +\textit{minor number}, che sono poi i due numeri mostrati dal comando +\texttt{ls -l} al posto della dimensione quando lo si esegue su un file di +dispositivo. + +Il \itindex{major~number} \textit{major number} identifica una classe di +dispositivi (ad esempio la seriale, o i dischi IDE) e serve in sostanza per +indicare al kernel quale è il modulo che gestisce quella classe di +dispositivi; per identificare uno specifico dispositivo di quella classe (ad +esempio una singola porta seriale, o una partizione di un disco) si usa invece +il \itindex{minor~number} \textit{minor number}. L'elenco aggiornato di questi +numeri con le relative corrispondenze ai vari dispositivi può essere trovato +nel file \texttt{Documentation/devices.txt} allegato alla documentazione dei +sorgenti del kernel. + +Data la crescita nel numero di dispositivi supportati, ben presto il limite +massimo di 256 si è rivelato troppo basso, e nel passaggio dai kernel della +serie 2.4 alla serie 2.6 è stata aumentata a 32 bit la dimensione del tipo +\type{dev\_t}, con delle dimensioni passate a 12 bit per il +\itindex{major~number} \textit{major number} e 20 bit per il +\itindex{minor~number} \textit{minor number}. La transizione però ha anche +comportato il passaggio di \type{dev\_t} a \index{tipo!opaco} tipo opaco, e la +necessità di specificare il numero tramite delle opportune macro, così da non +avere problemi di compatibilità con eventuali ulteriori estensioni. + +Le macro sono definite nel file \headfile{sys/sysmacros.h}, che viene +automaticamente incluso quando si include \headfile{sys/types.h}; si possono +pertanto ottenere i valori del \itindex{major~number} \textit{major number} e +\itindex{minor~number} \textit{minor number} di un dispositivo rispettivamente +con le macro \macro{major} e \macro{minor}: +\begin{functions} + \headdecl{sys/types.h} + \funcdecl{int \macro{major}(dev\_t dev)} + Restituisce il \itindex{major~number} \textit{major number} del dispositivo + \param{dev}. + + \funcdecl{int \macro{minor}(dev\_t dev)} + Restituisce il \itindex{minor~number} \textit{minor number} del dispositivo + \param{dev}. +\end{functions} +\noindent mentre una volta che siano noti \itindex{major~number} \textit{major + number} e \itindex{minor~number} \textit{minor number} si potrà costruire il +relativo identificativo con la macro \macro{makedev}: +\begin{functions} + \headdecl{sys/types.h} + \funcdecl{dev\_t \macro{minor}(int major, int minor)} + + Restituisce l'identificativo di un dispositivo dati \itindex{major~number} + \textit{major number} e \itindex{minor~number} \textit{minor number}. +\end{functions} + +\index{file!di~dispositivo|)} + +Infine con lo standard POSIX.1-2001 è stata introdotta una funzione specifica +per creare una fifo (tratteremo le fifo in in sez.~\ref{sec:ipc_named_pipe}); +la funzione è \funcd{mkfifo} ed il suo prototipo è: +\begin{functions} + \headdecl{sys/types.h} \headdecl{sys/stat.h} + + \funcdecl{int mkfifo(const char *pathname, mode\_t mode)} + + Crea una fifo. + + \bodydesc{La funzione restituisce zero in caso di successo e -1 per un + errore, nel qual caso \var{errno} assumerà i valori \errval{EACCES}, + \errval{EEXIST}, \errval{ENAMETOOLONG}, \errval{ENOENT}, \errval{ENOSPC}, + \errval{ENOTDIR} e \errval{EROFS}.} +\end{functions} + +La funzione crea la fifo \param{pathname} con i permessi \param{mode}. Come +per \func{mknod} il file \param{pathname} non deve esistere (neanche come link +simbolico); al solito i permessi specificati da \param{mode} vengono +modificati dal valore di \itindex{umask} \textit{umask}. + + \subsection{I file temporanei} \label{sec:file_temp_file} @@ -2646,7 +2730,7 @@ controllo e la creazione si ha giusto lo spazio per una possibile \itindex{race~condition} \textit{race condition} (si ricordi quanto visto in sez.~\ref{sec:proc_race_cond}). -Le \acr{glibc} provvedono varie funzioni per generare nomi di file temporanei, +La \acr{glibc} provvede varie funzioni per generare nomi di file temporanei, di cui si abbia certezza di unicità al momento della generazione; storicamente la prima di queste funzioni create a questo scopo era \funcd{tmpnam},\footnote{la funzione è stata deprecata nella revisione @@ -2727,8 +2811,8 @@ maniera sicura l'accesso ad un file temporaneo, il suo prototipo è: La funzione restituisce direttamente uno stream già aperto (in modalità \code{r+b}, si veda sez.~\ref{sec:file_fopen}) e pronto per l'uso, che viene automaticamente cancellato alla sua chiusura o all'uscita dal programma. Lo -standard non specifica in quale directory verrà aperto il file, ma le -\acr{glibc} prima tentano con \const{P\_tmpdir} e poi con \file{/tmp}. Questa +standard non specifica in quale directory verrà aperto il file, ma la +\acr{glibc} prima tenta con \const{P\_tmpdir} e poi con \file{/tmp}. Questa funzione è \index{funzioni!rientranti} rientrante e non soffre di problemi di \itindex{race~condition} \textit{race condition}. @@ -2782,7 +2866,7 @@ sez.~\ref{sec:file_open}), in questo modo al ritorno della funzione si ha la certezza di essere stati i creatori del file, i cui permessi (si veda sez.~\ref{sec:file_perm_overview}) sono impostati al valore \code{0600} (lettura e scrittura solo per il proprietario).\footnote{questo è vero a - partire dalle \acr{glibc} 2.0.7, le versioni precedenti delle \acr{glibc} e + partire dalla \acr{glibc} 2.0.7, le versioni precedenti della \acr{glibc} e le vecchie \acr{libc5} e \acr{libc4} usavano il valore \code{0666} che permetteva a chiunque di leggere e scrivere i contenuti del file.} Di questa funzione esiste una variante \funcd{mkostemp}, introdotta @@ -2802,7 +2886,7 @@ nell'apertura del file. In OpenBSD è stata introdotta un'altra funzione simile alle precedenti, \funcd{mkdtemp}, che crea invece una directory temporanea;\footnote{la - funzione è stata introdotta nelle \acr{glibc} a partire dalla versione + funzione è stata introdotta nella \acr{glibc} a partire dalla versione 2.1.91 ed inserita nello standard POSIX.1-2008.} il suo prototipo è: \begin{prototype}{stlib.h}{char *mkdtemp(char *template)} Genera una directory temporanea. @@ -3439,7 +3523,7 @@ quello di ultima modifica. Quando si usa uno di questi valori speciali per Queste due funzioni sono una estensione definita in una recente revisione dello standard POSIX (la POSIX.1-2008); sono state introdotte a partire dal -kernel 2.6.22, e supportate dalle \acr{glibc} a partire dalla versione +kernel 2.6.22, e supportate dalla \acr{glibc} a partire dalla versione 2.6.\footnote{in precedenza, a partire dal kernel 2.6.16, era stata introdotta la funzione \funcm{futimesat} seguendo una bozza della revisione dello standard poi modificata, questa funzione, sostituita da \func{utimensat}, è @@ -4432,7 +4516,7 @@ tab.~\ref{tab:extended_attribute_class}, si hanno i seguenti casi: \end{basedescript} Le funzioni per la gestione degli attributi estesi, come altre funzioni di -gestione avanzate specifiche di Linux, non fanno parte delle \acr{glibc}, e +gestione avanzate specifiche di Linux, non fanno parte della \acr{glibc}, e sono fornite da una apposita libreria, \texttt{libattr}, che deve essere installata a parte;\footnote{la versione corrente della libreria è \texttt{libattr1}.} pertanto se un programma le utilizza si dovrà indicare @@ -4677,7 +4761,7 @@ tramite una libreria, \texttt{libacl} che nasconde i dettagli implementativi delle ACL e presenta ai programmi una interfaccia che fa riferimento allo standard POSIX 1003.1e. -Anche in questo caso le funzioni di questa libreria non fanno parte delle +Anche in questo caso le funzioni di questa libreria non fanno parte della \acr{glibc} e devono essere installate a parte;\footnote{la versione corrente della libreria è \texttt{libacl1}, e nel caso si usi Debian la si può installare con il pacchetto omonimo e con il collegato \texttt{libacl1-dev} @@ -6433,11 +6517,11 @@ Una terza \textit{capability} con vasto campo di applicazione è \const{CAP\_SYS\_ADMIN}, che copre una serie di operazioni amministrative, come impostare le quote disco (vedi sez.\ref{sec:disk_quota}), attivare e disattivare la swap, montare, rimontare e smontare filesystem (vedi -sez.~\ref{sec:sys_file_config}), effettuare operazioni di controllo su +sez.~\ref{sec:filesystem_mounting}), effettuare operazioni di controllo su qualunque oggetto dell'IPC di SysV (vedi sez.~\ref{sec:ipc_sysv}), operare sugli attributi estesi dei file di classe \texttt{security} o \texttt{trusted} -(vedi sez.~\ref{sec:file_xattr}), specificare un \ids{UID} arbitrario -nella trasmissione delle credenziali dei socket (vedi +(vedi sez.~\ref{sec:file_xattr}), specificare un \ids{UID} arbitrario nella +trasmissione delle credenziali dei socket (vedi sez.~\ref{sec:socket_credential_xxx}), assegnare classi privilegiate (\const{IOPRIO\_CLASS\_RT} e prima del kernel 2.6.25 anche \const{IOPRIO\_CLASS\_IDLE}) per lo scheduling dell'I/O (vedi @@ -6558,7 +6642,7 @@ Dato che le precedenti funzioni, oltre ad essere specifiche di Linux, non garantiscono la stabilità nell'interfaccia, è sempre opportuno effettuare la gestione delle \textit{capabilities} utilizzando le funzioni di libreria a questo dedicate. Queste funzioni, che seguono quanto previsto nelle bozze -dello standard POSIX.1e, non fanno parte delle \acr{glibc} e sono fornite in +dello standard POSIX.1e, non fanno parte della \acr{glibc} e sono fornite in una libreria a parte,\footnote{la libreria è \texttt{libcap2}, nel caso di Debian può essere installata con il pacchetto omonimo.} pertanto se un programma le utilizza si dovrà indicare esplicitamente l'uso della suddetta @@ -7230,11 +7314,12 @@ programmi e librerie) di cui il server potrebbe avere bisogno. % LocalWords: mountflags NODEV ENXIO dummy devfs magic MGC RDONLY NOSUID MOVE % LocalWords: NOEXEC SYNCHRONOUS REMOUNT MANDLOCK NODIRATIME umount MNT statfs % LocalWords: fstatfs fstab mntent ino bound orig new setpcap metadati sysfs +% LocalWords: bind DIRSYNC lsattr Hierarchy FHS SHARED UNBINDABLE shared REC +% LocalWords: subtree SILENT log unbindable BUSY EAGAIN EXPIRE DETACH NOFOLLOW +% LocalWords: lazy encfs sshfs setfsent getfsent getfsfile getfsspec endfsent +% LocalWords: setmntent getmntent addmntent endmntent hasmntopt %%% Local Variables: %%% mode: latex %%% TeX-master: "gapil" %%% End: -% LocalWords: bind DIRSYNC lsattr Hierarchy FHS SHARED UNBINDABLE shared REC -% LocalWords: subtree SILENT log unbindable BUSY EAGAIN EXPIRE DETACH NOFOLLOW -% LocalWords: lazy