la struttura dei files in un sistema unix; esamineremo poi come è strutturato
il sistema base di protezioni e controllo di accesso ai files, e tutta
l'interfaccia che permette la manipolazione dei vari attributi di files e
-directories. Tutto quello che riguarda invece la manipolazione dei contenuti e
+directories. Tutto quello che riguarda invece la manipolazione dei contenuti è
lasciato ai capitoli successivi.
Le funzioni che esamineremo in questo capitolo pertanto sono quelle che
\label{sec:filedir_org}
L'organizzazione dei nomi dei file deriva direttamente dall'organizzazione dei
-medesimi nell'albero descritto brevemente in \ref{sec:fileintr_overview}; una
-directory comunque, come già specificato in \ref{sec:fileintr_vfs}, è solo un
-particolare tipo di file che contiene le informazioni che associano un nome al
-contenuto. Per questo, anche se è usuale parlare di ``file in una directory''
-in realtà una directory contiene solo dei riferimenti ai file, non i file
-stessi.
-
-I nomi contenuti nelle directory sono chiamati componenti (\textit{file name
- components}), un file può essere indicato rispetto alla directory corrente
-semplicemente specificando il nome da essa contenuto. Una directory contiene
-semplicemente un elenco di questi componenti, che possono corrispondere a un
-qualunque oggetto del filesystem, compresa un'altra directory; l'albero viene
-appunto creato inserendo directory in altre directory.
-
-Il nome di file generico è composto da una serie di \textsl{componenti}
-separati da una \texttt{/} (in linux più \texttt{/} consecutive sono
-considerate equivalenti ad una sola). Il nome completo di un file viene
-usualmente chiamato \textit{pathname}, e anche se il manuale della glibc
-depreca questo nome (poichè genererebbe confusione, dato che con \textit{path}
-si indica anche un insieme di directory su cui effettuare una ricerca, come
-quello in cui si cercano i comandi) l'uso è ormai così comune che è senz'altro
-più chiaro dell'alternativa proposta.
-
-Il processo con cui si associa ad un pathname uno specifico file (cioè si
-identifica l'inode a cui fare riferimento) è chiamato risoluzione del nome
-(\textit{file name resolution} o \textit{pathname resolution}).
-La risoluzione viene fatta esaminando il pathname da destra a sinistra e
-localizzando ogni componente nella directory indicata dal componente
-precedente: ovviamente perché il procedimento funzioni occorre che i
-componenti indicati come directory esistano e siano effettivamente directory,
-inoltre i permessi devono consentire l'accesso.
+medesimi nell'albero descritto brevemente in \secref{sec:fileintr_overview};
+una directory comunque, come già specificato in \secref{sec:fileintr_vfs}, è
+solo un particolare tipo di file che contiene le informazioni che associano un
+nome al contenuto. Per questo, anche se è usuale parlare di ``file in una
+directory'' in realtà una directory contiene solo delle etichette per fare
+riferimento ai file stessi.
+
+I manuale delle librerie del C chiama i nomi contenuti nelle directory
+\textsl{componenti} (in inglese \textit{file name components}), noi li
+chiameremo più semplicemente nomi. Un file può essere indicato rispetto alla
+directory corrente semplicemente specificando il nome da essa contenuto. Una
+directory contiene semplicemente un elenco di questi nomi, che possono
+corrispondere a un qualunque oggetto del filesystem, compresa un'altra
+directory; l'albero viene appunto creato inserendo directory in altre
+directory.
+
+Il nome completo di file generico è composto da una serie di questi
+\textsl{componenti} separati da una \texttt{/} (in linux più \texttt{/}
+consecutive sono considerate equivalenti ad una sola). Il nome completo di un
+file viene usualmente chiamato \textit{pathname}, e anche se il manuale della
+glibc depreca questo nome (poichè genererebbe confusione, dato che con
+\textit{path} si indica anche un insieme di directory su cui effettuare una
+ricerca, come quello in cui si cercano i comandi) l'uso è ormai così comune
+che è senz'altro più chiaro dell'alternativa proposta.
+
+Il processo con cui si associa ad un pathname uno specifico file è chiamato
+risoluzione del nome (\textit{file name resolution} o \textit{pathname
+ resolution}). La risoluzione viene fatta esaminando il pathname da destra a
+sinistra e localizzando ogni nome nella directory indicata dal nome
+precedente: ovviamente perché il procedimento funzioni occorre che i nomi
+indicati come directory esistano e siano effettivamente directory, inoltre i
+permessi devono consentire l'accesso.
Se il pathname comincia per \texttt{/} la ricerca parte dalla directory radice
del processo; questa, a meno di un \textit{chroot} (su cui torneremo in
-seguito, vedi \ref{sec:proc_chroot}) è la stessa per tutti i processi ed
+seguito, vedi \secref{sec:proc_chroot}) è la stessa per tutti i processi ed
equivale alla directory radice dell'albero (come descritto in
-\ref{sec:fileintr_overview}): in questo caso si parla di un pathname
+\secref{sec:fileintr_overview}): in questo caso si parla di un pathname
\textsl{assoluto}. Altrimenti la ricerca parte dalla directory corrente (su
-cui torneremo più avanti in \ref{sec:filedir_work_dir}) ed il pathname è detto
-\textsl{relativo}.
+cui torneremo più avanti in \secref{sec:filedir_work_dir}) ed il pathname è
+detto \textsl{relativo}.
-I componenti \texttt{.} e \texttt{..} hanno un significato speciale e vengono
+I nomi \texttt{.} e \texttt{..} hanno un significato speciale e vengono
inseriti in ogni directory, il primo fa riferimento alla directory corrente e
il secondo alla directory \textsl{genitore} (\textit{parent directory}) cioè
la directory che contiene il riferimento alla directory corrente; nel caso
questa sia la directory radice allora il riferimento è a se stessa.
-\section{La manipolazione di files e directories}
-\label{sec:filedir_handling}
+\section{L'architettura di gestione dei file}
+\label{sec:filedir_file_handling}
Per capire fino in fondo le proprietà di files e directories in un sistema
unix ed il funzionamento delle relative funzioni di manipolazione occorre una
-breve introduzione agli oggetti su cui è basato un filesystem unix; in
-particolare si riprenderanno, approfondendoli, i concetti di \textit{inode} e
-\textit{dentry} brevemente introdotti in \ref{sec:fileintr_vfs}.
+breve introduzione sulla gestione dei medesimo e sugli oggetti su cui è basato
+un filesystem unix; in particolare si riprenderà, approfondendolo sul piano
+dell'uso nelle funzioni di libreria, il concetto di \textit{inode} di cui
+abbiamo brevemente accennato le caratteristiche (dal lato dell'implementazione
+nel kernel) in \secref{sec:fileintr_vfs}.
-\subsection{Il funzionamento di un filesystem}
+\subsection{Il funzionamento di un filesystem unix}
\label{sec:filedir_filesystem}
-Come già accennato in \ref{sec:fileintr_overview} linux (ed ogni unix in
+Come già accennato in \secref{sec:fileintr_overview} linux (ed ogni unix in
generale) organizza i dati che tiene su disco attraverso l'uso di un
filesystem. Una delle caratteristiche di linux rispetto agli altri unix è
quella di poter supportare grazie al VFS una enorme quantità di filesystem
Dato un disco lo spazio fisico viene usualmente diviso in partizioni; ogni
partizione può contenere un filesystem; quest'ultimo è in genere strutturato
-secondo \nfig, con una lista di inodes all'inizio e il resto dello spazio aa
+secondo \nfig, con una lista di inodes all'inizio e il resto dello spazio a
disposizione per i dati e le directory.
\begin{figure}[htb]
\label{fig:filedir_disk_filesys}
\end{figure}
-Se si va ad esaminare come è strutturata l'informazione all'interno del
-filesystem (tralasciando le parti che non riguardano direttamente la gestione
-di file e directory come il super-block) avremo una situazione del tipo di
-quella esposta in \nfig.
-
+Se si va ad esaminare come è strutturata l'informazione all'interno di un
+singolo filesystem (tralasciando le parti connesse alla strutturazione e al
+funzionamento del filesystem stesso come il super-block) avremo una situazione
+del tipo di quella esposta in \nfig.
\begin{figure}[htb]
\centering
\caption{Organizzazione di un filesystem}
\label{fig:filedir_filesys_detail}
\end{figure}
+da questa figura si evidenzano alcune caratteristiche su cui è bene porre
+attenzione in quanto sono fondamentali per capire il funzionamento delle
+funzioni che manipolano i file e le directory su cui torneremo fra poco; in
+particolare è opportuno ricordare sempre che:
-
-Quanto mostrato in \curfig\ mette in evidenza alcune caratteristiche di un
-filesystem unix su cui è bene porre attenzione in quanto sono fondamentali per
-capire il funzionamento delle funzioni che manipolano i file e le directory su
-cui torneremo fra poco; in particolare è opportuno ricordare sempre che:
-
-\begin{itemize}
+\begin{enumerate}
\item L'\textit{inode} contiene tutte le informazioni riguardanti il file: il
tipo di file, i permessi di accesso, le dimensioni, i puntatori ai blocchi
fisici che contengono i dati e così via; le informazioni che la funzione
- \texttt{stat} fornisce provengono dall'inode; dentro una directory si
- troverà solo il nome del file e il numero dell'inode ad esso associato, cioè
- una \textit{dentry}.
+ \texttt{stat} fornisce provengono dall'\textit{inode}; dentro una directory
+ si troverà solo il nome del file e il numero dell'\textit{inode} ad esso
+ associato, cioè quella che da qui in poi chiameremo una \textsl{voce}
+ (traduzione approssimata dell'inglese \textit{directory entry}, che non
+ useremo anche per evitare confusione con le \textit{dentries} del kernel di
+ cui si parlava in \secref{sec:fileintr_vfs}).
-\item Come mostrato in \curfig si possono avere più dentries che puntano allo
- stesso inode. Ogni inode ha un contatore che contiene il numero di
- riferimenti (\textit{link count}) che sono stati fatti ad esso, solo quando
- questo contatore si annulla il file può essere cancellato. Per questo in
- generale non esiste una funzione che cancelli un file, ma solo la funzione
- \texttt{unlink} che si chiama così proprio perché che toglie un riferimento
- da una directory (cancellando la dentry), il che non comporta
- automaticamente pure la eliminazione dei blocchi sul disco.
+\item Come mostrato in \curfig si possono avere più voci che puntano allo
+ stesso \textit{inode}. Ogni \textit{inode} ha un contatore che contiene il
+ numero di riferimenti (\textit{link count}) che sono stati fatti ad esso;
+ solo quando questo contatore si annulla i dati del file vengono
+ effettivamente rimossi dal disco. Per questo la funzione per cancellare un
+ file si chiama \texttt{unlink}, ed in realtà non cancella affatto i dati del
+ file, ma si limita a eliminare la relativa voce da una directory e
+ decrementare il numero di riferimenti nell'\textit{inode}.
+
+\item Il numero di \textit{inode} nella voce si riferisce ad un \textit{inode}
+ nello stesso filesystem e non ci può essere una directory che contiene
+ riferimenti ad \textit{inodes} relativi ad altri filesystem. Questo limita
+ l'uso del comando \texttt{ln} (che crea una nuova voce per un file
+ esistente, con la funzione \texttt{link}) al filesystem corrente.
-\item Siccome il numero di inode nella dentry si riferisce ad un inode nello
- stesso filesystem non ci può essere una directory che contiene riferimenti
- ad inodes relativi ad altri filesystem, questo limita l'uso del comando
- \texttt{ln} (che crea una nuova dentry per un file esistente, con la
- funzione \texttt{link}) al filesystem corrente.
-
\item Quando si cambia nome ad un file senza cambiare filesystem il contenuto
- del file non deve essere spostato, ma basta creare una nuova dentry per
- l'inode in questione rimuovendo la vecchia (che è la modalità in cui opera
- normalmente il comando \texttt{mv} attraveso la funzione \texttt{rename}).
+ del file non deve essere spostato, viene semplicemente creata una nuova voce
+ per l'\textit{inode} in questione e rimossa la vecchia (questa è la modalità
+ in cui opera normalmente il comando \texttt{mv} attraverso la funzione
+ \texttt{rename}).
-\end{itemize}
+\end{enumerate}
-Infine è bene avere presente che esiste un numero di riferimenti anche per le
-directories, se a partire dalla situazione mostrata in \curfig\ creiamo una
-nuova directory \texttt{textdir} avremo una situazione come quella in \nfig,
-dove per chiarezza abbiamo aggiunto dei numeri di inode.
+Infine è bene avere presente che essendo file pure loro, esiste un numero di
+riferimenti anche per le directories; per cui se ad esempio a partire dalla
+situazione mostrata in \curfig\ creiamo una nuova directory \texttt{textdir}
+nella directory corrente avremo una situazione come quella in \nfig, dove per
+chiarezza abbiamo aggiunto dei numeri di inode.
La nuova directory avrà allora un numero di riferimenti pari a due, in quanto
è referenziata dalla directory da cui si era partiti (in cui è inserita la
-nuova dentry che fa riferiemto a \texttt{textdir}) e dalla dentry \texttt{.}
+nuova voce che fa riferimento a \texttt{textdir}) e dalla voce \texttt{.}
che è sempre inserita in ogni directory; questo vale sempre per ogni directory
che non contenga a sua volta altre directories. Al contempo la directory da
cui si era partiti avrà un numero di riferiementi di almeno tre, in quanto
-adesso sarà referenziata anche dalla dentry \texttt{..} di \texttt{textdir}.
+adesso sarà referenziata anche dalla voce \texttt{..} di \texttt{textdir}.
\subsection{Le funzioni \texttt{link} e \texttt{unlink}}
ma data la struttura del sistema ci sono due metodi sostanzialmente diversi
per fare questa operazione.
-Come si è appena visto l'accesso al contenuto di un file su disco avviene
-attraverso il suo \textit{inode}, e il nome che si trova in una directory è
-solo una etichetta associata ad un puntatore a detto inode. Questo significa
-che la realizzazione di un link è immediata in quanto uno stesso file può
-avere tanti nomi diversi allo stesso tempo, dati da altrettante diverse
-associazioni allo stesso inode; si noti poi che nessuno di questi nomi viene
-ad assumere una particolare preferenza rispetto agli altri.
+Come si è appena detto l'accesso al contenuto di un file su disco avviene
+attraverso il suo inode, e il nome che si trova in una directory è solo una
+etichetta associata ad un puntatore a detto inode. Questo significa che la
+realizzazione di un link è immediata in quanto uno stesso file può avere tanti
+nomi diversi allo stesso tempo, dati da altrettante diverse associazioni allo
+stesso inode; si noti poi che nessuno di questi nomi viene ad assumere una
+particolare preferenza rispetto agli altri.
Per aggiungere un nome ad un inode si utilizza la funzione \texttt{link}; si
suole chiamare questo tipo di associazione un collegamento diretto (o
-\textit{hard link}). La creazione di un nuovo link diretto non copia il
-contenuto del file, ma si limita ad aumentare di uno il numero di referenze al
-file aggiungendo il nuovo nome ai precedenti. Si noti che uno stesso file può
-essere così richiamato in diverse directory.
-
-\begin{itemize}
-\item \texttt{int link(const char * oldname, const char * newname)}
-
- Crea un nuovo link diretto al file indicato da \texttt{oldname} dandogli
- nome \texttt{newname}.
+\textit{hard link}). Il prototipo della funzione e le sue caratteritiche
+principali, come risultano dalla man page, sono le seguenti:
+\begin{prototype}{unistd.h}
+{int link(const char * oldpath, const char * newpath)}
+ Crea un nuovo collegamento diretto al file indicato da \texttt{oldpath}
+ dandogli nome \texttt{newpath}.
La funzione restituisce zero in caso di successo e -1 per un errore, in caso
- di errore. La variabile \texttt{errno} viene settata secondo i codici di
- errore standard di accesso ai files (trattati in dettaglio in
- \ref{sec:filedir_access_control}) ai quali si aggiungono i seguenti:
-
- \begin{itemize}
- \item \texttt{EXDEV} \texttt{oldname} e \texttt{newname} non sono sullo
+ di errore. La variabile \texttt{errno} viene settata secondo i seguenti
+ codici di errore:
+ \begin{errlist}
+ \item \texttt{EXDEV} \texttt{oldpath} e \texttt{newpath} non sono sullo
stesso filesystem.
- \item \texttt{EPERM} il filesystem che contiene \texttt{oldname} e
- \texttt{newname} non supporta i link diretti.
- \item \texttt{EACCESS}
- Non c'è il permesso di scrittura per la directory in cui si vuole creare
- il nuovo link.
- \item \texttt{EEXIST} Un file (o una directory) con quel nome esiste di
+ \item \texttt{EPERM} il filesystem che contiene \texttt{oldpath} e
+ \texttt{newpath} non supporta i link diretti, oppure \texttt{oldpath} è
+ una directory.
+ \item \texttt{EFAULT} una delle stringhe passate come parametri è fuori
+ dello spazio di indirizzi del processo.
+ \item \texttt{EACCESS} errore di accesso (mancano i permessi per scrivere o
+ per attraversare le directories), vedi \secref{sec:filedir_access_control}
+ per i dettagli.
+ \item \texttt{ENAMETOOLONG} una dei due pathname è troppo lungo.
+ \item \texttt{ENOENT} un componente di \texttt{oldpath} o \texttt{newpath}
+ non esiste o è un link simbolico spezzato.
+ \item \texttt{ENOTDIR} un componente di \texttt{oldpath} o \texttt{newpath}
+ non è una directory.
+ \item \texttt{ENOMEM} il kernel non ha a disposizione memoria sufficiente a
+ completare l'operazione.
+ \item \texttt{EROFS} la directory su cui si vuole inserire il nuovo link è
+ su un filesystem montato readonly.
+ \item \texttt{EEXIST} un file (o una directory) con quel nome esiste di
già.
- \item \texttt{EMLINK} Ci sono troppi link al file \texttt{oldname} (il
+ \item \texttt{EMLINK} ci sono troppi link al file \texttt{oldpath} (il
numero massimo è specificato dalla variabile \texttt{LINK\_MAX}, vedi
- \ref{sec:xxx_limits}.
- \item \texttt{ENOSPC} La directory in cui si vuole creare il link è piena e
- non può essere ampliata.
- \item \texttt{EROFS} La directory su cui si vuole inserire il nuovo link è
- su un filesystem montato readonly.
- \end{itemize}
-\end{itemize}
-
-
+ \secref{sec:xxx_limits}).
+ \item \texttt{ELOOP} si incontrati troppi link simbolici nella risoluzione
+ di \texttt{oldpath} o \texttt{newpath}.
+ \item \texttt{ENOSPC} la directory in cui si vuole creare il link non ha
+ spazio per ulteriori voci.
+ \item \texttt{EIO} c'è stato un errore di input/output.
+ \end{errlist}
+\end{prototype}
+
+La creazione di un nuovo collegamento diretto non copia il contenuto del file,
+ma si limita ad aumentare di uno il numero di referenze al file aggiungendo il
+nuovo nome ai precedenti. Si noti che uno stesso file può essere così
+richiamato in diverse directory.
+
+Per quanto dicevamo in \secref{sec:filedir_filesystem} la creazione del
+collegamento diretto è possibile solo se entrambi i pathname sono nello stesso
+filesytem; inoltre il filesystem deve supportare i collegamenti diretti (non è
+il caso ad esempio del filesystem \texttt{vfat} di windows).
+
+La funzione opera sui file ordinari, come sugli altri oggetti del filesystem,
+ma solo l'amministratore è in grado di creare un collegamento diretto ad
+un'altra directory, questo lo si fa perché in questo caso è possibile creare
+dei circoli nel filesystem (vedi \secref{sec:filedir_symlink}) che molti
+programmi non sono in grado di gestire e la cui rimozione diventa estremamente
+complicata (in genere occorre far girare il programma \texttt{fsck} per
+riparare il filesystem); data la sua pericolosità in linux questa
+caratteristica è stata disabilitata, e la funzione restituisce l'errore
+\texttt{EPERM}.
+
+La rimozione di un file (o più precisamente della voce che lo referenzia) si
+effettua con la funzione \texttt{unlink}; il suo prototipo è il seguente:
+
+\begin{prototype}{unistd.h}{int unlink(const char * pathname)}
+ Cancella il nome specificato dal pathname nella relativa directory e
+ decrementa il numero di riferimenti nel relativo inode. Nel caso di link
+ simbolico cancella il link simbolico; nel caso di socket, fifo o file di
+ dispositivo rimuove il nome, ma come per i file i processi che hanno aperto
+ uno di questi oggetti possono continuare ad utilizzarlo.
+
+ La funzione restituisce zero in caso di successo e -1 per un errore, nel
+ qual caso il file non viene toccato. La variabile \texttt{errno} viene
+ settata secondo i seguenti codici di errore:
+ \begin{errlist}
+ \item \texttt{EACCESS} errore di accesso (mancano i permessi per scrivere o
+ per attraversare le directories), vedi \secref{sec:filedir_access_control}
+ per i dettagli.
+ \item \texttt{EPERM} il filesystem che contiene \texttt{pathname} non
+ consente l'operazione.
+ \item \texttt{EFAULT} la stringa passata come parametro è fuori dello spazio
+ di indirizzi del processo.
+ \item \texttt{ENAMETOOLONG} il pathname troppo lungo.
+ \item \texttt{ENOENT} uno dei componenti del pathname non esiste o è un link
+ simbolico spezzato.
+ \item \texttt{ENOTDIR} uno dei componenti del pathname non è una directory.
+ \item \texttt{EISDIR} \texttt{pathname} fa riferimento a una directory.
+ \item \texttt{ENOMEM} il kernel non ha a disposizione memoria sufficiente a
+ completare l'operazione.
+ \item \texttt{EROFS} \texttt{pathname} è su un filesystem montato in sola
+ lettura.
+ \item \texttt{ELOOP} ci sono troppi link simbolici nella risoluzione del
+ pathname.
+ \item \texttt{EIO} errore di input/output.
+ \end{errlist}
+\end{prototype}
+
+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 (torneremo in
+dettaglio sui permessi e gli attributi fra poco), se inoltre lo
+\textit{sticky} bit è settato 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
+della nome dalla directory e l'incremento/decremento del numero di riferimenti
+nell'inode deve essere una operazione atomica (cioè non interrompibile da
+altri) processi, per questo entrambe queste funzioni sono realizzate tramite
+una singola system call.
+
+Si ricordi infine che il file non viene eliminato dal disco fintanto che tutti
+i riferimenti ad esso sono stati cancellati, solo quando il \textit{link
+ count} mantenuto nell'inode diventa zero lo spazio occupato viene rimosso. A
+questo però si aggiunge una altra condizione, e cioè che non ci siano processi
+che abbiano detto file aperto. Come accennato 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
+\texttt{unlink} subito dopo.
\subsection{Le funzioni \texttt{remove} e \texttt{rename}}
\label{sec:filedir_cre_canc}
+Al contrario di quanto avviene con altri unix in linux non è possibile usare
+\texttt{unlink} sulle directory, per cancellare una directory si può usare la
+funzione \texttt{rmdir} (vedi \secref{sec:filedir_dir_creat_rem}), oppure la
+funzione \texttt{remove}. Questa è la funzione prevista dallo standard ANSI C
+per cancellare un file o una directory (e funziona anche per i sistemi che non
+supportano i link diretti), che per i file è identica alla \texttt{unlink} e
+per le directory è identica alla \texttt{rmdir}:
+
+\begin{prototype}{stdio.h}{int remove(const char *pathname)}
+ Cancella un nome dal filesystem. Usa \texttt{unlink} per i file e
+ \texttt{rmdir} per le directory.
+
+ La funzione restituisce zero in caso di successo e -1 per un errore, nel
+ qual caso il file non viene toccato. Per i codici di errori vedi quanto
+ riportato nella descrizione di \texttt{unlink} e \texttt{rmdir}.
+\end{prototype}
+
+Per cambiare nome ad un file si usa invece la funzione \texttt{rename}, il
+vantaggio nell'uso di questa funzione al posto della chiamata successiva di
+\texttt{unlink} e \texttt{link} è che l'operazione è eseguita atomicamente, in
+questo modo non c'è la possibilità che un processo che cerchi di accedere al
+nuovo nome dopo che il vecchio è stato cambiato lo trovi mancante.
+
+\begin{prototype}{stdio.h}
+{int rename(const char *oldpath, const char *newpath)}
+ Rinomina un file, spostandolo fra directory diverse quando richiesto.
+
+ La funzione restituisce zero in caso di successo e -1 per un errore, nel
+ qual caso il file non viene toccato. La variabile \texttt{errno} viene
+ settata secondo i seguenti codici di errore:
+ \begin{errlist}
+ \item \texttt{EFAULT} la stringa \texttt{filename} è fuori dello spazio di
+ indirizzi del processo.
+ \item \texttt{EACCESS} Non c'è il permesso di scrittura per la directory in
+ cui si vuole creare il nuovo link o una delle directory del pathname non
+ consente la ricerca (permesso di esecuzione).
+ \item \texttt{EPERM} il pathname indica una directory o il filesystem che
+ contiene \texttt{filename} non consente l'operazione.
+ \item \texttt{EROFS} I file sono su un filesystem montato in sola lettura.
+ \item \texttt{ENAMETOOLONG} il pathname è troppo lungo.
+ \item \texttt{ENOENT} Uno dei componenti del pathname non esiste o è un link
+ simbolico spezzato.
+ \item \texttt{ENOTDIR} Uno dei componenti del pathname non è una directory.
+ \item \texttt{ENOMEM} Memoria insufficiente nel kernel.
+ \item \texttt{ELOOP} Ci sono troppi link simbolici nella risoluzione del
+ pathname.
+ \item \texttt{EISDIR}
+ \item \texttt{EXDEV}
+ \item \texttt{ENOTEMPTY}
+ \item \texttt{EBUSY}
+ \item \texttt{EINVAL}
+ \item \texttt{EMLINK}
+ \item \texttt{ENOSPC}
+
+ \end{errlist}
+\end{prototype}
\subsection{I link simbolici}
\label{sec:filedir_sym_link}
-Siccome tutto ciò funziona facendo riferimento ad un inode, questa funzione
-può essere applicata soltanto per file che risiedono sullo stesso filesystem,
-(dato che solo in questo caso è garantita l'unicità dell'inode) e solo per
-filesystem di tipo unix. Inoltre in linux non è consentito eseguire un link
-diretto ad una directory.
+Siccome la funzione \texttt{link} crea riferimenti agli inodes, essa può
+funzionare soltanto per file che risiedono sullo stesso filesystem, dato che
+in questo caso è garantita l'unicità dell'inode, e solo per un filesystem di
+tipo unix. Inoltre 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,
alle informazioni del link invece che a quelle del file a cui esso fa
riferimento.
-Le funzioni per operare sui link sono le seguenti, esse sono tutte dichiarate
-nell'header file \texttt{unistd.h}.
+Le funzioni per operare sui link simbolici sono le seguenti, esse sono tutte
+dichiarate nell'header file \texttt{unistd.h}.
-\begin{itemize}
-\item \texttt{int symlink(const char * oldname, const char * newname)}
-
+\begin{prototype}{unistd.h}
+{int symlink(const char * oldname, const char * newname)}
Crea un nuovo link simbolico al file indicato da \texttt{oldname} dandogli
nome \texttt{newname}.
La funzione restituisce zero in caso di successo e -1 per un errore, in caso
di errore. La variabile \texttt{errno} viene settata secondo i codici di
errore standard di accesso ai files (trattati in dettaglio in
- \ref{sec:filedir_access_control}) ai quali si aggiungono i seguenti:
+ \secref{sec:filedir_access_control}) ai quali si aggiungono i seguenti:
+ \begin{errlist}
+ \item \texttt{EEXIST} Un file (o una directory) con quel nome esiste di
+ già.
+ \item \texttt{EROFS} La directory su cui si vuole inserire il nuovo link è
+ su un filesystem montato readonly.
+ \item \texttt{ENOSPC} La directory o il filesystem in cui si vuole creare il
+ link è piena e non c'è ulteriore spazio disponibile.
+ \item \texttt{ELOOP} Ci sono troppi link simbolici nella risoluzione di
+ \texttt{oldname} o di \texttt{newname}.
+ \end{errlist}
+\end{prototype}
+
+Dato che la funzione \texttt{open} segue i link simbolici, è necessaria usare
+un'altra funzione quando si vuole leggere il contenuto di un link simbolico,
+questa funzione è la:
- \begin{itemize}
+\begin{prototype}{unistd.h}
+{int readlink(const char * path, char * buff, size\_t size)}
+ Legge il contnuto del link simbolico indicato da \texttt{path} nel buffer
+ \texttt{buff} di dimensione \texttt{size}. Non chiude la stringa con un
+ carattere nullo e la tronca a \texttt{size} nel caso il buffer sia troppo
+ piccolo pe contenerla.
+
+
+ La funzione restituisce il numero di caratteri letti dentro \texttt{buff} o
+ -1 per un errore, in caso di errore. La variabile \texttt{errno} viene
+ settata secondo i codici di errore:
+ \begin{errlist}
\item \texttt{EEXIST} Un file (o una directory) con quel nome esiste di
già.
\item \texttt{EROFS} La directory su cui si vuole inserire il nuovo link è
link è piena e non c'è ulteriore spazio disponibile.
\item \texttt{ELOOP} Ci sono troppi link simbolici nella risoluzione di
\texttt{oldname} o di \texttt{newname}.
- \end{itemize}
-\end{itemize}
+ \end{errlist}
+\end{prototype}
+
+
+\section{Il controllo di accesso ai file}
+\label{sec:filedir_access_control}
+\subsection{I flag \texttt{suid} e \texttt{sgid}}
+\label{sec:filedir_suid_sgid}
+
+\subsection{La titolarità di nuovi files e directory}
+\label{sec:filedir_ownership}
+
+\subsection{La funzione \texttt{access}}
+\label{sec:filedir_access}
+
+\subsection{La funzione \texttt{umask}}
+\label{sec:filedir_umask}
+
+\subsection{Le funzioni \texttt{chmod} e \texttt{fchmod}}
+\label{sec:filedir_chmod}
+
+\subsection{Il flag \texttt{stiky}}
+\label{sec:filedir_stiky}
+
+\subsection{Le funzioni \texttt{chown}, \texttt{fchown} e \texttt{lchown}}
+\label{sec:filedir_chown}
+
+
+
+\section{La manipolazione delle directories}
+\label{sec:filedir_dir_handling}
+
\subsection{Le funzioni \texttt{mkdir} e \texttt{rmdir}}
\label{sec:filedir_dir_creat_rem}
Per creare una nuova directory si può usare la seguente funzione, omonima
-dell'analogo comando di shell \texttt{mkdir}; per accedere alla funzioni il
-programma deve includere il file \texttt{sys/stat.h}.
+dell'analogo comando di shell \texttt{mkdir}; per accedere ai tipi usati
+programma deve includere il file \texttt{sys/types.h}.
-\begin{itemize}
-\item \texttt{char * mkdir (const char * dirname, mode\_t mode)}
-
+\begin{prototype}{sys/stat.h}
+{int mkdir (const char * dirname, mode\_t mode)}
Questa funzione crea una nuova directory vuota con il nome indicato da
\texttt{dirname}, assegnandole i permessi indicati da \texttt{mode}. Il nome
può essere indicato con il pathname assoluto o relativo.
La funzione restituisce zero in caso di successo e -1 per un errore, in caso
di errore \texttt{errno} viene settata secondo i codici di errore standard
di accesso ai files (trattati in dettaglio in
- \ref{sec:filedir_access_control}) ai quali si aggiungono i seguenti:
- \begin{itemize}
+ \secref{sec:filedir_access_control}) ai quali si aggiungono i seguenti:
+ \begin{errlist}
\item \texttt{EACCESS}
Non c'è il permesso di scrittura per la directory in cui si vuole inserire
la nuova directory.
la nuova directory.
\item \texttt{EROFS} La directory su cui si vuole inserire la nuova
directory è su un filesystem montato readonly.
- \end{itemize}
-\end{itemize}
+ \end{errlist}
+\end{prototype}
\subsection{Accesso alle directory}
la funzione \texttt{opendir} apre uno di questi stream e la funzione
\texttt{readdir} legge il contenuto della directory, i cui elementi sono le
\textit{directory entries} (da distinguersi da quelle della cache di cui
-parlavamo in \ref{sec:fileintr_vfs}) in una opportuna struttura
+parlavamo in \secref{sec:fileintr_vfs}) in una opportuna struttura
\texttt{struct dirent}.
directory corrente di qualunque comando da essa lanciato.
Le funzioni qui descritte servono esaminare e cambiare la directory di lavoro
-corrente. I prototipi di queste funzioni sono dichiarati in \texttt{unistd.h}.
+corrente.
-\begin{itemize}
-\item \texttt{char * getcwd (char * buffer, size\_t size)}
-
+\begin{prototype}{unistd.h}{char * getcwd (char * buffer, size\_t size)}
Restituisce il filename completo della directory di lavoro corrente nella
stringa puntata da \texttt{buffer}, che deve essere precedentemente
allocata, per una dimensione massima di \texttt{size}. Si può anche
La funzione restituisce il puntatore \texttt{buffer} se riesce,
\texttt{NULL} se fallisce, in quest'ultimo caso la variabile
\texttt{errno} è settata con i seguenti codici di errore:
-
- \begin{itemize}
+ \begin{errlist}
\item \texttt{EINVAL} L'argomento \texttt{size} è zero e \texttt{buffer} non
è nullo.
\item \texttt{ERANGE} L'argomento \texttt{size} è più piccolo della
\item \texttt{EACCES} Manca il permesso di lettura o di ricerca su uno dei
componenti del pathname (cioè su una delle directory superiori alla
corrente).
- \end{itemize}
-\end{itemize}
+ \end{errlist}
+\end{prototype}
Di questa funzione esiste una versione \texttt{char * getwd(char * buffer)}
fatta per compatibilità all'indietro con BSD, che non consente di specificare
la dimensione del buffer; esso deve essere allocato in precedenza ed avere una
dimensione superiore a \texttt{PATH\_MAX} (di solito 256 byters, vedi
-\ref{sec:xxx_limits}; il problema è che in linux non esiste una dimensione
+\secref{sec:xxx_limits}; il problema è che in linux non esiste una dimensione
superiore per un pathname, per cui non è detto che il buffer sia sufficiente a
contenere il nome del file, e questa è la ragione principale per cui questa
funzione è deprecata.
e non solo tramite il filename; per questo motivo ci sono due diverse funzioni
per cambiare directory di lavoro.
-\begin{itemize}
-\item \texttt{int chdir (const char * pathname)}
-
+\begin{prototype}{unistd.h}{int chdir (const char * pathname)}
Come dice il nome (che significa \textit{change directory}) questa funzione
serve a cambiare la directory di lavoro a quella speficata dal pathname
contenuto nella stringa \texttt{pathname}.
+\end{prototype}
-\item \texttt{int fchdir (int filedes)} analoga alla precedente, ma usa un
- file descriptor invece del pathname.
-
+\begin{prototype}{unistd.h}{int fchdir (int filedes)}
+ Analoga alla precedente, ma usa un file descriptor invece del pathname.
Entrambe le funzioni restituiscono zero in caso di successo e -1 per un
errore, in caso di errore \texttt{errno} viene settata secondo i codici di
errore standard di accesso ai files (trattati in dettaglio in
- \ref{sec:filedir_access_control}) ai quali si aggiunge il codice
+ \secref{sec:filedir_access_control}) ai quali si aggiunge il codice
\texttt{ENOTDIR} nel caso il \texttt{filename} indichi un file che non sia
una directory.
-\end{itemize}
-
-
-
+\end{prototype}
\section{La manipolazione delle caratteristiche dei files}
\label{sec:filedir_infos}
-Si ricordi che in unix non esistono i tipi di file e che non c'è nessun
-supporto per le estensioni come parte del filesystem. Ciò non ostante molti
-programmi adottano delle convenzioni per i nomi dei file, ad esempio il codice
-C normalmente si mette in file con l'estensione .c, ma questa è, appunto, solo
-una convenzione.
-
-
\subsection{Le funzioni \texttt{stat}, \texttt{fstat} e \texttt{lstat}}
\label{sec:filedir_stat}
-\section{Il controllo di accesso ai file}
-\label{sec:filedir_access_control}
-
-
-\subsection{I flag \texttt{suid} e \texttt{sgid}}
-\label{sec:filedir_suid_sgid}
-
-\subsection{La titolarità di nuovi files e directory}
-\label{sec:filedir_ownership}
-
-\subsection{La funzione \texttt{access}}
-\label{sec:filedir_access}
-
-\subsection{La funzione \texttt{umask}}
-\label{sec:filedir_umask}
-
-\subsection{Le funzioni \texttt{chmod} e \texttt{fchmod}}
-\label{sec:filedir_chmod}
-
-\subsection{Il flag \texttt{stiky}}
-\label{sec:filedir_stiky}
-
-\subsection{Le funzioni \texttt{chown}, \texttt{fchown} e \texttt{lchown}}
-\label{sec:filedir_chown}
-
-
%La struttura fondamentale che contiene i dati essenziali relativi ai file è il
%cosiddetto \textit{inode}; questo conterrà informazioni come il
%tipo di file (file di dispositivo, directory, file di dati, per un elenco
-%completo vedi \ntab), i permessi (vedi \ref{sec:file_perms}), le date (vedi
-%\ref{sec:file_times}).
+%completo vedi \ntab), i permessi (vedi \secref{sec:file_perms}), le date (vedi
+%\secref{sec:file_times}).