%% filedir.tex
%%
%% Copyright (C) 2000-2012 Simone Piccardi.  Permission is granted to
%% copy, distribute and/or modify this document under the terms of the GNU Free
%% Documentation License, Version 1.1 or any later version published by the
%% Free Software Foundation; with the Invariant Sections being "Un preambolo",
%% with no Front-Cover Texts, and with no Back-Cover Texts.  A copy of the
%% license is included in the section entitled "GNU Free Documentation
%% License".
%%

\chapter{La gestione di file e directory}
\label{cha:files_and_dirs}

In questo capitolo tratteremo in dettaglio le modalità con cui si gestiscono
file e directory, iniziando da un approfondimento dell'architettura del
sistema illustrata a grandi linee in sez.~\ref{sec:file_arch_overview} ed
illustrando le principali caratteristiche di un filesystem e le interfacce
che consentono di controllarne il montaggio e lo smontaggio. 

Esamineremo poi le funzioni di libreria che si usano per copiare, spostare e
cambiare i nomi di file e directory e l'interfaccia che permette la
manipolazione dei loro attributi. Tratteremo inoltre la struttura di base del
sistema delle protezioni e del controllo dell'accesso ai file e le successive
estensioni (\textit{Extended Attributes}, ACL, quote disco,
\textit{capabilities}). Tutto quello che riguarda invece la gestione dell'I/O
sui file è lasciato al capitolo successivo.



\section{L'architettura della gestione dei file}
\label{sec:file_arch_func}

In questa sezione tratteremo con maggiori dettagli rispetto a quanto visto in
sez.~\ref{sec:file_arch_overview} il \textit{Virtual File System} di Linux e
come il kernel può gestire diversi tipi di filesystem, descrivendo prima le
caratteristiche generali di un filesystem di un sistema unix-like, per poi
fare una panoramica sul filesystem più usato con Linux, l'\acr{ext2} ed i suoi
successori.


\subsection{Il funzionamento del \textit{Virtual File System} di Linux}
\label{sec:file_vfs_work}

% NOTE articolo interessante:
% http://www.ibm.com/developerworks/linux/library/l-virtual-filesystem-switch/index.html?ca=dgr-lnxw97Linux-VFSdth-LXdW&S_TACT=105AGX59&S_CMP=GRlnxw97

\itindbeg{Virtual~File~System}

Come illustrato brevemente in sez.~\ref{sec:file_arch_overview} in Linux il
concetto di \textit{everything is a file} è stato implementato attraverso il
\textit{Virtual File System}, la cui struttura generale è illustrata in
fig.~\ref{fig:file_VFS_scheme}.  Il VFS definisce un insieme di funzioni che
tutti i filesystem devono implementare per l'accesso ai file che contengono e
l'interfaccia che consente di eseguire l'I/O sui file, che questi siano di
dati o dispositivi. 

\itindbeg{inode}

L'interfaccia fornita dal VFS comprende in sostanza tutte le funzioni che
riguardano i file, le operazioni implementate dal VFS sono realizzate con una
astrazione che prevede quattro tipi di oggetti strettamente correlati: i
filesystem, le \textit{dentry}, gli \textit{inode} ed i file. A questi oggetti
corrispondono una serie di apposite strutture definite dal kernel che
contengono come campi le funzioni di gestione e realizzano l'infrastruttura
del VFS. L'interfaccia è molto complessa, ne faremo pertanto una trattazione
estremamente semplificata che consenta di comprenderne i principi
di funzionamento.

Il VFS usa una tabella mantenuta dal kernel che contiene il nome di ciascun
filesystem supportato, quando si vuole inserire il supporto di un nuovo
filesystem tutto quello che occorre è chiamare la funzione
\code{register\_filesystem} passando come argomento la struttura
\kstruct{file\_system\_type} (la cui definizione è riportata in
fig.~\ref{fig:kstruct_file_system_type}) relativa a quel filesystem. Questa
verrà inserita nella tabella, ed il nuovo filesystem comparirà in
\procfile{/proc/filesystems}.

\begin{figure}[!htb]
  \footnotesize \centering
  \begin{minipage}[c]{\textwidth}
    \includestruct{listati/file_system_type.h}
  \end{minipage}
  \normalsize 
  \caption{Estratto della struttura \kstructd{file\_system\_type} usata dal
    VFS (da \texttt{include/linux/fs.h}).}
  \label{fig:kstruct_file_system_type}
\end{figure}

La struttura \kstruct{file\_system\_type}, oltre ad una serie di dati interni,
come il nome del tipo di filesystem nel campo \var{name},\footnote{quello che
  viene riportato in \procfile{/proc/filesystems} e che viene usato come
  valore del parametro dell'opzione \texttt{-t} del comando \texttt{mount} che
  indica il tipo di filesystem.}  contiene i riferimenti alle funzioni di base
che consentono l'utilizzo di quel filesystem. In particolare la funzione
\code{mount} del quarto campo è quella che verrà invocata tutte le volte che
si dovrà effettuare il montaggio di un filesystem di quel tipo. Per ogni nuovo
filesystem si dovrà allocare una di queste strutture ed inizializzare i
relativi campi con i dati specifici di quel filesystem, ed in particolare si
dovrà creare anche la relativa versione della funzione \code{mount}.

\itindbeg{pathname}
\itindbeg{pathname~resolution}

Come illustrato in fig.~\ref{fig:kstruct_file_system_type} questa funzione
restituisce una \textit{dentry}, abbreviazione che sta per \textit{directory
  entry}. Le \textit{dentry} sono gli oggetti che il kernel usa per eseguire
la \textit{pathname resolution}, ciascuna di esse corrisponde ad un
\textit{pathname} e contiene il riferimento ad un \textit{inode}, che come
vedremo a breve è l'oggetto usato dal kernel per identificare un un
file.\footnote{in questo caso si parla di file come di un qualunque oggetto
  generico che sta sul filesystem e non dell'oggetto file del VFS cui
  accennavamo prima.} La \textit{dentry} ottenuta dalla chiamata alla funzione
\code{mount} sarà inserita in corrispondenza al \textit{pathname} della
directory in cui il filesystem è stato montato.

% NOTA: struct dentry è dichiarata in include/linux/dcache.h

Le \textit{dentry} sono oggetti del VFS che vivono esclusivamente in memoria,
nella cosiddetta \textit{directory entry cache} (spesso chiamata in breve
\textit{dcache}). Ogni volta che una \textit{system call} specifica un
\textit{pathname} viene effettuata una ricerca nella \textit{dcache} per
ottenere immediatamente la \textit{dentry} corrispondente,\footnote{il buon
  funzionamento della \textit{dcache} è in effetti di una delle parti più
  critiche per le prestazioni del sistema.} che a sua volta ci darà, tramite
l'\textit{inode}, il riferimento al file.

Dato che normalmente non è possibile mantenere nella \textit{dcache} le
informazioni relative a tutto l'albero dei file la procedura della
\textit{pathname resolution} richiede un meccanismo con cui riempire gli
eventuali vuoti. Il meccanismo prevede che tutte le volte che si arriva ad una
\textit{dentry} mancante venga invocata la funzione \texttt{lookup}
dell'\textit{inode} associato alla \textit{dentry} precedente nella
risoluzione del \textit{pathname},\footnote{che a questo punto è una
  directory, per cui si può cercare al suo interno il nome di un file.} il cui
scopo è risolvere il nome mancante e fornire la sua \textit{dentry} che a
questo punto verrà inserita nella cache.

Dato che tutte le volte che si monta un filesystem la funzione \texttt{mount}
della corrispondente \kstruct{file\_system\_type} inserisce la \textit{dentry}
iniziale nel \itindex{mount~point} \textit{mount point} dello stesso, si avrà
comunque un punto di partenza. Inoltre essendo questa \textit{dentry} relativa
a quel tipo di filesystem essa farà riferimento ad un \textit{inode} di quel
filesystem, e come vedremo questo farà sì che venga eseguita una
\texttt{lookup} adatta per effettuare la risoluzione dei nomi per quel
filesystem.

\itindend{pathname}
\itindend{pathname~resolution}

% Un secondo effetto della chiamata funzione \texttt{mount} di
% \kstruct{file\_system\_type} è quello di allocare una struttura
% \kstruct{super\_block} per ciascuna istanza montata, che contiene le
% informazioni generali di un qualunque filesystem montato, come le opzioni di
% montaggio, le dimensioni dei blocchi, quando il filesystem è stato montato
% ecc. Fra queste però viene pure inserta, nel campo \var{s\_op}, una ulteriore
% struttura \kstruct{super\_operations}, il cui contenuto sono i puntatori
% alle funzioni di gestione di un filesystem, anche inizializzata in modo da
% utilizzare le versioni specifiche di quel filesystem.

L'oggetto più importante per il funzionamento del VFS è probabilmente
l'\textit{inode}, ma con questo nome si può fare riferimento a due cose
diverse.  La prima è la struttura su disco (su cui torneremo anche in
sez.~\ref{sec:file_filesystem}) che fa parte della organizzazione dei dati
realizzata dal filesystem e che contiene le informazioni relative alle
proprietà (i cosiddetti \textsl{metadati}) di ogni oggetto presente su di esso
(si intende al solito uno qualunque dei tipi di file di
tab.~\ref{tab:file_file_types}).

La seconda è la corrispondente struttura \kstruct{inode}, della cui
definizione si è riportato un estratto in
fig.~\ref{fig:kstruct_inode}.\footnote{l'estratto fa riferimento alla versione
  del kernel 2.6.37.} Questa struttura viene mantenuta in memoria ed è a
questa che facevamo riferimento quando parlavamo dell'\textit{inode} associato
a ciascuna \textit{dentry}. Nella struttura in memoria sono presenti gli
stessi \textsl{metadati} memorizzati su disco, che vengono letti quando questa
struttura viene allocata e trascritti all'indietro se modificati.

\begin{figure}[!htb]
  \footnotesize \centering
  \begin{minipage}[c]{\textwidth}
    \includestruct{listati/inode.h}
  \end{minipage}
  \normalsize 
  \caption{Estratto della struttura \kstructd{inode} del kernel (da
    \texttt{include/linux/fs.h}).}
  \label{fig:kstruct_inode}
\end{figure}

Il fatto che la struttura \kstruct{inode} sia mantenuta in memoria,
direttamente associata ad una \textit{dentry}, rende sostanzialmente immediate
le operazioni che devono semplicemente effettuare un accesso ai dati in essa
contenuti: è così ad esempio che viene realizzata la \textit{system call}
\func{stat} che vedremo in sez.~\ref{sec:file_stat}. Rispetto ai dati salvati
sul disco questa struttura contiene però anche quanto necessario alla
implementazione del VFS, ed in particolare è importante il campo \var{i\_op}
che, come illustrato in fig.~\ref{fig:kstruct_inode}, contiene il puntatore ad
una struttura di tipo \kstruct{inode\_operation}, la cui definizione si può
trovare nel file \texttt{include/kernel/fs.h} dei sorgenti del kernel.

Questa struttura non è altro che una tabella di funzioni, ogni suo membro cioè
è un puntatore ad una funzione e, come suggerisce il nome della struttura
stessa, queste funzioni sono quelle che definiscono le operazioni che il VFS
può compiere su un \textit{inode}. Si sono riportate in
tab.~\ref{tab:file_inode_operations} le più rilevanti.

\begin{table}[htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|l|}
    \hline
    \textbf{Funzione} & \textbf{Operazione} \\
    \hline
    \hline
    \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:link_symlink_rename}).\\
    \textsl{\code{unlink}} & Cancella un \textit{hard link} (vedi
                             sez.~\ref{sec:link_symlink_rename}).\\
    \textsl{\code{symlink}}& Crea un collegamento simbolico (vedi
                             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
                             sez.~\ref{sec:file_dir_creat_rem}).\\
    \textsl{\code{mknod}}  & Crea un \index{file!speciali} file speciale (vedi
                             sez.~\ref{sec:file_mknod}).\\
    \textsl{\code{rename}} & Cambia il nome di un file (vedi
                             sez.~\ref{sec:link_symlink_rename}).\\
    \textsl{\code{lookup}}&  Risolve il nome di un file.\\
    \hline
  \end{tabular}
  \caption{Le principali operazioni sugli \textit{inode} definite tramite
    \kstruct{inode\_operation}.} 
  \label{tab:file_inode_operations}
\end{table}

Possiamo notare come molte di queste funzioni abbiano nomi sostanzialmente
identici alle varie \textit{system call} con le quali si gestiscono file e
directory, che tratteremo nel resto del capitolo. Quello che succede è che
tutte le volte che deve essere eseguita una \textit{system call}, o una
qualunque altra operazione su un \textit{inode} (come \texttt{lookup}) il VFS
andrà ad utilizzare la funzione corrispondente attraverso il puntatore
\var{i\_op}.

Sarà allora sufficiente che nella realizzazione di un filesystem si crei una
implementazione di queste funzioni per quel filesystem e si allochi una
opportuna istanza di \kstruct{inode\_operation} contenente i puntatori a dette
funzioni. A quel punto le strutture \kstruct{inode} usate per gli oggetti di
quel filesystem otterranno il puntatore alla relativa istanza di
\kstruct{inode\_operation} e verranno automaticamente usate le funzioni
corrette.

Si noti però come in tab.~\ref{tab:file_inode_operations} non sia presente la
funzione \texttt{open} che invece è citata in
tab.~\ref{tab:file_file_operations}.\footnote{essa può essere comunque
  invocata dato che nella struttura \kstruct{inode} è presente anche il
  puntatore \var{i\_fop} alla struttura \kstruct{file\_operation} che fornisce
  detta funzione.} Questo avviene perché su Linux l'apertura di un file
richiede comunque un'altra operazione che mette in gioco l'omonimo oggetto del
VFS: l'allocazione di una struttura di tipo \kstruct{file} che viene associata
ad ogni file aperto nel sistema.

I motivi per cui viene usata una struttura a parte sono diversi, anzitutto,
come illustrato in sez.~\ref{sec:file_fd}, questa è necessaria per le
operazioni eseguite dai processi con l'interfaccia dei file descriptor; ogni
processo infatti mantiene il riferimento ad una struttura \kstruct{file} per
ogni file che ha aperto, ed è tramite essa che esegue le operazioni di I/O.

Inoltre se le operazioni relative agli \textit{inode} fanno riferimento ad
oggetti posti all'interno di un filesystem e vi si applicano quindi le
funzioni fornite nell'implementazione di quest'ultimo, quando si apre un file
questo può essere anche un file di dispositivo, ed in questo caso il VFS
invece di usare le operazioni fornite dal filesystem (come farebbe per un file
di dati) dovrà invece ricorrere a quelle fornite dal driver del dispositivo.

\itindend{inode}

\begin{figure}[!htb]
  \footnotesize \centering
  \begin{minipage}[c]{\textwidth}
    \includestruct{listati/file.h}
  \end{minipage}
  \normalsize 
  \caption{Estratto della struttura \kstructd{file} del kernel (da
    \texttt{include/linux/fs.h}).}
  \label{fig:kstruct_file}
\end{figure}

Come si può notare dall'estratto di fig.~\ref{fig:kstruct_file}, la struttura
\kstruct{file} contiene, oltre ad alcune informazioni usate dall'interfaccia
dei file descriptor il cui significato emergerà più avanti, il puntatore
\var{f\_op} ad una struttura \kstruct{file\_operation}. Questa è l'analoga per
i file di \kstruct{inode\_operation}, e definisce le operazioni generiche
fornite dal VFS per i file. Si sono riportate in
tab.~\ref{tab:file_file_operations} le più significative.

\begin{table}[htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|p{8cm}|}
    \hline
    \textbf{Funzione} & \textbf{Operazione} \\
    \hline
    \hline
    \textsl{\code{open}}   & Apre il file (vedi sez.~\ref{sec:file_open}).\\
    \textsl{\code{read}}   & Legge dal file (vedi sez.~\ref{sec:file_read}).\\
    \textsl{\code{write}}  & Scrive sul file (vedi 
                             sez.~\ref{sec:file_write}).\\
    \textsl{\code{llseek}} & Sposta la posizione corrente sul file (vedi
                             sez.~\ref{sec:file_lseek}).\\
    \textsl{\code{ioctl}}  & Accede alle operazioni di controllo 
                             (vedi sez.~\ref{sec:file_ioctl}).\\
    \textsl{\code{readdir}}& Legge il contenuto di una directory (vedi 
                             sez.~\ref{sec:file_dir_read}).\\
    \textsl{\code{poll}}   & Usata nell'I/O multiplexing (vedi
                             sez.~\ref{sec:file_multiplexing}).\\
    \textsl{\code{mmap}}   & Mappa il file in memoria (vedi 
                             sez.~\ref{sec:file_memory_map}).\\
    \textsl{\code{release}}& Chiamata quando l'ultimo riferimento a un file 
                             aperto è chiuso.\\
    \textsl{\code{fsync}}  & Sincronizza il contenuto del file (vedi
                             sez.~\ref{sec:file_sync}).\\
    \textsl{\code{fasync}} & Abilita l'I/O asincrono (vedi
                             sez.~\ref{sec:file_asyncronous_io}) sul file.\\
    \hline
  \end{tabular}
  \caption{Operazioni sui file definite tramite \kstruct{file\_operation}.}
  \label{tab:file_file_operations}
\end{table}

Anche in questo caso tutte le volte che deve essere eseguita una
\textit{system call} o una qualunque altra operazione sul file il VFS andrà ad
utilizzare la funzione corrispondente attraverso il puntatore
\var{f\_op}. Dato che è cura del VFS quando crea la struttura all'apertura del
file assegnare a \var{f\_op} il puntatore alla versione di
\kstruct{file\_operation} corretta per quel file, sarà possibile scrivere allo
stesso modo sulla porta seriale come su un normale file di dati, e lavorare
sui file allo stesso modo indipendentemente dal filesystem.

Il VFS realizza la quasi totalità delle operazioni relative ai file grazie
alle funzioni presenti nelle due strutture \kstruct{inode\_operation} e
\kstruct{file\_operation}.  Ovviamente non è detto che tutte le operazioni
possibili siano poi disponibili in tutti i casi, ad esempio \code{llseek} non
sarà presente per un dispositivo come la porta seriale o per una fifo, mentre
sui file del filesystem \texttt{vfat} non saranno disponibili i permessi, ma
resta il fatto che grazie al VFS le \textit{system call} per le operazioni sui
file possono restare sempre le stesse nonostante le enormi differenze che
possono esserci negli oggetti a cui si applicano.
 

\itindend{Virtual~File~System}

% NOTE: documentazione interessante:
%       * sorgenti del kernel: Documentation/filesystems/vfs.txt
%       * http://thecoffeedesk.com/geocities/rkfs.html
%       * http://www.linux.it/~rubini/docs/vfs/vfs.html



\subsection{Il funzionamento di un filesystem Unix}
\label{sec:file_filesystem}

Come già accennato in sez.~\ref{sec:file_arch_overview} Linux (ed ogni sistema
unix-like) 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
diversi, ognuno dei quali avrà una sua particolare struttura e funzionalità
proprie.  Per questo non entreremo nei dettagli di un filesystem specifico, ma
daremo una descrizione a grandi linee che si adatta alle caratteristiche
comuni di qualunque filesystem di un sistema unix-like.

Una possibile strutturazione dell'informazione su un disco è riportata in
fig.~\ref{fig:file_disk_filesys}, dove si hanno tre filesystem su tre
partizioni. In essa per semplicità si è fatto riferimento alla struttura del
filesystem \acr{ext2}, che prevede una suddivisione dei dati in \textit{block
  group}.  All'interno di ciascun \textit{block group} viene anzitutto
replicato il cosiddetto \itindex{superblock} \textit{superblock}, (la
struttura che contiene l'indice iniziale del filesystem e che consente di
accedere a tutti i dati sottostanti) e creata una opportuna suddivisione dei
dati e delle informazioni per accedere agli stessi.  Sulle caratteristiche di
\acr{ext2} e derivati torneremo in sez.~\ref{sec:file_ext2}.

\itindbeg{inode}

È comunque caratteristica comune di tutti i filesystem per Unix,
indipendentemente da come poi viene strutturata nei dettagli questa
informazione, prevedere la presenza di due tipi di risorse: gli
\textit{inode}, cui abbiamo già accennato in sez.~\ref{sec:file_vfs_work}, che
sono le strutture che identificano i singoli oggetti sul filesystem, e i
blocchi, che invece attengono allo spazio disco che viene messo a disposizione
per i dati in essi contenuti.

\begin{figure}[!htb]
  \centering
  \includegraphics[width=12cm]{img/disk_struct}
  \caption{Organizzazione dello spazio su un disco in partizioni e
  filesystem.}
  \label{fig:file_disk_filesys}
\end{figure}

Se si va ad esaminare con maggiore dettaglio la strutturazione
dell'informazione all'interno del filesystem \textsl{ext2}, tralasciando i
dettagli relativi al funzionamento del filesystem stesso come la
strutturazione in gruppi dei blocchi, il \itindex{superblock}
\textit{superblock} e tutti i dati di gestione possiamo esemplificare la
situazione con uno schema come quello esposto in
fig.~\ref{fig:file_filesys_detail}.

\begin{figure}[!htb]
  \centering
  \includegraphics[width=12cm]{img/filesys_struct}
  \caption{Strutturazione dei dati all'interno di un filesystem.}
  \label{fig:file_filesys_detail}
\end{figure}

Da fig.~\ref{fig:file_filesys_detail} si evidenziano alcune delle
caratteristiche di base di un filesystem, che restano le stesse anche su
filesystem la cui organizzazione dei dati è totalmente diversa da quella
illustrata, e sulle quali è bene porre attenzione visto che sono fondamentali
per capire il funzionamento delle funzioni che manipolano i file e le
directory che tratteremo nel prosieguo del capitolo. In particolare è
opportuno tenere sempre presente che:


\begin{enumerate}
  
\item L'\textit{inode} contiene i cosiddetti \textsl{metadati}, vale dire le
  informazioni riguardanti le proprietà del file come oggetto del filesystem:
  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 \func{stat} (vedi sez.~\ref{sec:file_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; il nome non è una
  proprietà del file e non viene mantenuto nell'\textit{inode}. Da da qui in
  poi chiameremo il nome del file contenuto in una directory
  ``\textsl{voce}'', come traduzione della nomenclatura inglese
  \textit{directory entry} che non useremo per evitare confusione con le
  \textit{dentry} del kernel viste in sez.~\ref{sec:file_vfs_work}.
  
\item Come mostrato in fig.~\ref{fig:file_filesys_detail} per i file
  \texttt{macro.tex} e \texttt{gapil\_macro.tex}, ci possono avere più voci
  che fanno riferimento allo stesso \textit{inode}. Fra le proprietà di un
  file mantenute nell'\textit{inode} c'è anche il contatore con il numero di
  riferimenti che sono stati fatti ad esso, il cosiddetto \textit{link
    count}.\footnote{mantenuto anche nel campo \var{i\_nlink} della struttura
    \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: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
  directory si riferisce ad questo numero e non ci può essere una directory
  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: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: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
  in genere vengono gestite come tali anche dai diversi filesystem; è pertanto
  possibile esaurire sia lo spazio disco (il caso più comune) che lo spazio
  per gli \textit{inode}. Nel primo caso non sarà possibile allocare ulteriore
  spazio, ma si potranno creare file (vuoti), nel secondo non si potranno
  creare nuovi file, ma si potranno estendere quelli che ci
  sono.\footnote{questo comportamento non è generale, alcuni filesystem
    evoluti possono evitare il problema dell'esaurimento degli \textit{inode}
    riallocando lo spazio disco libero per i blocchi.}

\end{enumerate}

\begin{figure}[!htb]
  \centering 
  \includegraphics[width=12cm]{img/dir_links}
  \caption{Organizzazione dei \textit{link} per le directory.}
  \label{fig:file_dirs_link}
\end{figure}

Infine tenga presente che, essendo file pure loro, il numero di riferimenti
esiste anche per le directory. Per questo se a partire dalla situazione
mostrata in fig.~\ref{fig:file_filesys_detail} creiamo una nuova directory
\file{img} nella directory \file{gapil}, avremo una situazione come quella
illustrata in fig.~\ref{fig:file_dirs_link}.

La nuova directory avrà un numero di riferimenti pari a due, in quanto è
referenziata dalla directory da cui si era partiti (in cui è inserita la nuova
voce che fa riferimento a \texttt{img}) e dalla voce interna ``\texttt{.}''
che è presente in ogni directory.  Questo è il valore che si troverà sempre
per ogni directory che non contenga a sua volta altre directory. Al contempo,
la directory da cui si era partiti avrà un numero di riferimenti di almeno
tre, in quanto adesso sarà referenziata anche dalla voce ``\texttt{..}'' di
\texttt{img}. L'aggiunta di una sottodirectory fa cioè crescere di uno il
\textit{link count} della directory genitrice.

\itindend{inode}


\subsection{Alcuni dettagli sul filesystem \textsl{ext2} e successori}
\label{sec:file_ext2}


Benché non esista ``il'' filesystem di Linux, dato che esiste un supporto
nativo di diversi filesystem che sono in uso da anni, quello che gli avvicina
di più è la famiglia di filesystem evolutasi a partire dal \textit{second
  extended filesystem}, o \acr{ext2}. Il filesystem \acr{ext2} ha subito un
grande sviluppo e diverse evoluzioni, fra cui l'aggiunta del
\textit{journaling} con il passaggio ad \acr{ext3}, che probabilmente è ancora
il filesystem più diffuso, ed una serie di ulteriori miglioramenti con il
successivo \acr{ext4}, che sta iniziando a sostituirlo gradualmente. In futuro
è previsto che questo debba essere sostituito da un filesystem completamente
diverso, \acr{btrfs}, che dovrebbe diventare il filesystem standard di Linux,
ma questo al momento è ancora in fase di sviluppo.\footnote{si fa riferimento
  al momento dell'ultima revisione di di questo paragrafo, l'inizio del 2012.}

Il filesystem \acr{ext2} nasce come filesystem nativo per Linux a partire
dalle prime versioni del kernel e supporta tutte le caratteristiche di un
filesystem standard Unix: è in grado di gestire nomi di file lunghi (256
caratteri, estensibili a 1012) e supporta una dimensione massima dei file fino
a 4~Tb. I successivi filesystem \acr{ext3} ed \acr{ext4} sono evoluzioni di
questo filesystem, e sia pure con molti miglioramenti ed estensioni
significative ne mantengono le caratteristiche fondamentali.

Oltre alle caratteristiche standard, \acr{ext2} fornisce alcune estensioni che
non sono presenti su un classico filesystem di tipo Unix; le principali sono
le seguenti:
\begin{itemize}
\item i \textit{file attributes} consentono di modificare il comportamento del
  kernel quando agisce su gruppi di file. Possono essere impostati su file e
  directory e in quest'ultimo caso i nuovi file creati nella directory
  ereditano i suoi attributi.
\item sono supportate entrambe le semantiche di BSD e SVr4 come opzioni di
  montaggio. La semantica BSD comporta che i file in una directory sono creati
  con lo stesso identificatore di gruppo della directory che li contiene. La
  semantica SVr4 comporta che i file vengono creati con l'identificatore del
  gruppo primario del processo, eccetto il caso in cui la directory ha il bit
  di \acr{sgid} impostato (per una descrizione dettagliata del significato di
  questi termini si veda sez.~\ref{sec:file_access_control}), nel qual caso
  file e subdirectory ereditano sia il \ids{GID} che lo \acr{sgid}.
\item l'amministratore può scegliere la dimensione dei blocchi del filesystem
  in fase di creazione, a seconda delle sue esigenze: blocchi più grandi
  permettono un accesso più veloce, ma sprecano più spazio disco.
\item il filesystem implementa collegamenti simbolici veloci, in cui il nome
  del file non è salvato su un blocco, ma tenuto all'interno \itindex{inode}
  dell'\textit{inode} (evitando letture multiple e spreco di spazio), non
  tutti i nomi però possono essere gestiti così per limiti di spazio (il
  limite è 60 caratteri).
\item vengono supportati i file immutabili (che possono solo essere letti) per
  la protezione di file di configurazione sensibili, o file
  \textit{append-only} che possono essere aperti in scrittura solo per
  aggiungere dati (caratteristica utilizzabile per la protezione dei file di
  log).
\end{itemize}

La struttura di \acr{ext2} è stata ispirata a quella del filesystem di BSD: un
filesystem è composto da un insieme di blocchi, la struttura generale è quella
riportata in fig.~\ref{fig:file_filesys_detail}, in cui la partizione è divisa
in gruppi di blocchi.

Ciascun gruppo di blocchi contiene una copia delle informazioni essenziali del
filesystem (i \itindex{superblock} \textit{superblock} sono quindi ridondati)
per una maggiore affidabilità e possibilità di recupero in caso di corruzione
del \itindex{superblock} \textit{superblock} principale. L'utilizzo di
raggruppamenti di blocchi ha inoltre degli effetti positivi nelle prestazioni
dato che viene ridotta la distanza fra i dati e la tabella degli
\itindex{inode} \textit{inode}.

\begin{figure}[!htb]
  \centering
  \includegraphics[width=9cm]{img/dir_struct}  
  \caption{Struttura delle directory nel \textit{second extended filesystem}.}
  \label{fig:file_ext2_dirs}
\end{figure}

Le directory sono implementate come una \itindex{linked~list} \textit{linked
  list} con voci di dimensione variabile. Ciascuna voce della lista contiene
il numero di \itindex{inode} \textit{inode}, la sua lunghezza, il nome del
file e la sua lunghezza, secondo lo schema in fig.~\ref{fig:file_ext2_dirs};
in questo modo è possibile implementare nomi per i file anche molto lunghi
(fino a 1024 caratteri) senza sprecare spazio disco.

Con l'introduzione del filesystem \textit{ext3} sono state introdotte diverse
modifiche strutturali, la principale di queste è quella che \textit{ext3} è un
filesystem \textit{journaled}, è cioè in grado di eseguire una registrazione
delle operazioni di scrittura su un giornale (uno speciale file interno) in
modo da poter garantire il ripristino della coerenza dei dati del
filesystem\footnote{si noti bene che si è parlato di dati \textsl{del}
  filesystem, non di dati \textsl{nel} filesystem, quello di cui viene
  garantito un veloce ripristino è relativo ai dati della struttura interna
  del filesystem, non di eventuali dati contenuti nei file che potrebbero
  essere stati persi.} in brevissimo tempo in caso di interruzione improvvisa
della corrente o di crollo del sistema che abbia causato una interruzione
della scrittura dei dati sul disco.

Oltre a questo \textit{ext3} introduce ulteriori modifiche volte a migliorare
sia le prestazioni che la semplicità di gestione del filesystem, in
particolare per le directory si è passato all'uso di alberi binari con
indicizzazione tramite hash al posto delle \textit{linked list} che abbiamo
illustrato, ottenendo un forte guadagno di prestazioni in caso di directory
contenenti un gran numero di file.

% TODO (bassa priorità) portare a ext3, ext4 e btrfs ed illustrare le
% problematiche che si possono incontrare (in particolare quelle relative alla
% perdita di contenuti in caso di crash del sistema)
% TODO (media priorità) trattare btrfs quando sarà usato come stabile


\subsection{La gestione dell'uso dei filesystem}
\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 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} 
\fdecl{mount(const char *source, const char *target, const char
  *filesystemtype, \\ 
\phantom{mount(}unsigned long mountflags, const void *data)}
\fdesc{Monta un filesystem.} 
}
{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{EACCES}] non si ha il permesso di accesso su uno dei
    componenti del \textit{pathname}, o si è cercato di montare un filesystem
    disponibile in sola lettura senza aver specificato \const{MS\_RDONLY} o il
    device \param{source} è su un filesystem montato con l'opzione
    \const{MS\_NODEV}.
  \item[\errcode{EBUSY}] \param{source} è già montato, o non può essere
    rimontato in sola lettura perché ci sono ancora file aperti in scrittura,
    o non può essere montato su \param{target} perché la directory è ancora in
    uso.
  \item[\errcode{EINVAL}] il dispositivo \param{source} presenta un
    \itindex{superblock} \textit{superblock} non valido, o si è cercato di
    rimontare un filesystem non ancora montato, o di montarlo senza
    che \param{target} sia un \itindex{mount~point} \textit{mount point} o di
    spostarlo quando \param{target} non è un \itindex{mount~point}
    \textit{mount point} o è la radice.
  \item[\errcode{ELOOP}] si è cercato di spostare un \itindex{mount~point}
    \textit{mount point} su una sottodirectory di \param{source} o si sono
    incontrati troppi collegamenti simbolici nella risoluzione di un nome.
  \item[\errcode{EMFILE}] in caso di filesystem virtuale, la tabella dei
    dispositivi fittizi (chiamati \textit{dummy} nella documentazione inglese)
    è piena.
  \item[\errcode{ENODEV}] il tipo \param{filesystemtype} non esiste o non è
    configurato nel kernel.
  \item[\errcode{ENOTBLK}] non si è usato un \textit{block device} per
    \param{source} quando era richiesto.
  \item[\errcode{ENXIO}] il \itindex{major~number} \textit{major number} del
    dispositivo \param{source} è sbagliato.
  \item[\errcode{EPERM}] il processo non ha i privilegi di amministratore.
  \end{errlist} 
  ed inoltre \errval{EFAULT}, \errval{ENOMEM}, \errval{ENAMETOOLONG},
  \errval{ENOENT}, \errval{ENOTDIR} nel loro significato generico.}
\end{funcproto}

La funzione monta sulla directory indicata da \param{target}, detta
\itindex{mount~point} \textit{mount point}, il filesystem contenuto nel file
di dispositivo indicato da \param{source}. In entrambi i casi, come daremo per
assunto da qui in avanti tutte le volte che si parla di directory o file nel
passaggio di un argomento di una funzione, si intende che questi devono essere
indicati con la stringa contenente il loro \textit{pathname}.

Normalmente un filesystem è contenuto su un disco o una partizione, ma come
illustrato in sez.~\ref{sec:file_vfs_work} la struttura del
\itindex{Virtual~File~System} \textit{Virtual File System} è estremamente
flessibile e può essere usata anche per oggetti diversi da un disco. Ad
esempio usando il \textit{loop device} si può montare un file qualunque (come
l'immagine di un CD-ROM o di un floppy) che contiene l'immagine di un
filesystem, inoltre alcuni tipi di filesystem, come \texttt{proc} o
\texttt{sysfs} sono virtuali e non hanno un supporto che ne contenga i dati,
che invece sono generati al volo ad ogni lettura, e passati indietro al kernel
ad ogni scrittura.\footnote{costituiscono quindi un meccanismo di
  comunicazione, attraverso l'ordinaria interfaccia dei file, con il kernel.}

Il tipo di filesystem che si vuole montare è specificato
dall'argomento \param{filesystemtype}, che deve essere una delle stringhe
riportate nel file \procfile{/proc/filesystems} che, come accennato in
sez.~\ref{sec:file_vfs_work}, contiene l'elenco dei filesystem supportati dal
kernel. Nel caso si sia indicato un filesystem virtuale, che non è associato a
nessun file di dispositivo, il contenuto di \param{source} viene ignorato.

L'argomento \param{data} viene usato per passare le impostazioni relative alle
caratteristiche specifiche di ciascun filesystem. Si tratta di una stringa di
parole chiave (separate da virgole e senza spazi) che indicano le cosiddette
``\textsl{opzioni}'' del filesystem che devono essere impostate; in genere
viene usato direttamente il contenuto del parametro dell'opzione \texttt{-o}
del comando \texttt{mount}. I valori utilizzabili dipendono dal tipo di
filesystem e ciascuno ha i suoi, pertanto si rimanda alla documentazione della
pagina di manuale di questo comando e dei singoli filesystem.

Dopo l'esecuzione della funzione il contenuto del filesystem viene resto
disponibile nella directory specificata come \itindex{mount~point}
\textit{mount point}, il precedente contenuto di detta directory viene
mascherato dal contenuto della directory radice del filesystem montato. Fino
ai kernel della serie 2.2.x non era possibile montare un filesystem se un
\textit{mount point} era già in uso. 

A partire dal kernel 2.4.x inoltre è divenuto possibile sia spostare
atomicamente un \itindex{mount~point} \textit{mount point} da una directory ad
un'altra, sia montare lo stesso filesystem in diversi \itindex{mount~point}
\textit{mount point}, sia montare più filesystem sullo stesso
\itindex{mount~point} \textit{mount point} impilandoli l'uno sull'altro, nel
qual caso vale comunque quanto detto in precedenza, e cioè che solo il
contenuto dell'ultimo filesystem montato sarà visibile.

Oltre alle opzioni specifiche di ciascun filesystem, che si passano nella
forma della lista di parole chiave indicata con l'argomento \param{data},
esistono pure alcune opzioni che si possono applicare in generale, anche se
non è detto che tutti i filesystem le supportino, che si specificano tramite
l'argomento \param{mountflags}.  L'argomento inoltre può essere utilizzato per
modificare il comportamento della funzione \func{mount}, facendole compiere
una operazione diversa (ad esempio un rimontaggio, invece che un montaggio).

In Linux \param{mountflags} deve essere un intero a 32 bit; fino ai kernel
della serie 2.2.x i 16 più significativi avevano un valore riservato che
doveva essere specificato obbligatoriamente,\footnote{il valore era il
  \itindex{magic~number} \textit{magic number} \code{0xC0ED}, si può usare la
  costante \const{MS\_MGC\_MSK} per ottenere la parte di \param{mountflags}
  riservata al \textit{magic number}, mentre per specificarlo si può dare un
  OR aritmetico con la costante \const{MS\_MGC\_VAL}.} e si potevano usare
solo i 16 meno significativi. Oggi invece, con un numero di opzioni superiore,
sono utilizzati tutti e 32 i bit, ma qualora nei 16 più significativi sia
presente detto valore, che non esprime una combinazione valida, esso viene
ignorato. Il valore dell'argomento deve essere espresso come maschera binaria
e i vari bit che lo compongono, detti anche \textit{mount flags}, devono
essere impostati con un OR aritmetico dei valori dalle costanti riportate
nell'elenco seguente:

\begin{basedescript}{\desclabelwidth{2.cm}\desclabelstyle{\nextlinelabel}}
\itindbeg{bind~mount}
\item[\const{MS\_BIND}] Effettua un cosiddetto \textit{bind mount}, in cui è
  possibile montare una directory di un filesystem in un'altra directory,
  l'opzione è disponibile a partire dai kernel della serie 2.4. In questo caso
  verranno presi in considerazione solo gli argomenti \param{source}, che
  stavolta indicherà la directory che si vuole montare e non un file di
  dispositivo, e \param{target} che indicherà la directory su cui verrà
  effettuato il \textit{bind mount}. Gli argomenti \param{filesystemtype}
  e \param{data} vengono ignorati.

  In sostanza quello che avviene è che in corrispondenza del \textit{pathname}
  indicato da \param{target} viene montato \itindex{inode} l'\textit{inode}
  di \param{source}, così che la porzione di albero dei file presente sotto
  \param{source} diventi visibile allo stesso modo sotto
  \param{target}. Trattandosi esattamente dei dati dello stesso filesystem,
  ogni modifica fatta in uno qualunque dei due rami di albero sarà visibile
  nell'altro, visto che entrambi faranno riferimento agli stessi
  \textit{inode}.

  Dal punto di vista del \itindex{Virtual~File~System} VFS l'operazione è
  analoga al montaggio di un filesystem proprio nel fatto che anche in questo
  caso si inserisce in corrispondenza della \textit{dentry} di \texttt{target}
  un diverso \itindex{inode} \textit{inode}, che stavolta, invece di essere
  quello della radice del filesystem indicato da un file di dispositivo, è
  quello di una directory già montata.

  Si tenga presente che proprio per questo sotto \param{target} comparirà il
  contenuto che è presente sotto \param{source} all'interno del filesystem in
  cui quest'ultima è contenuta. Questo potrebbe non corrispondere alla
  porzione di albero che sta sotto \param{source} qualora in una
  sottodirectory di quest'ultima si fosse effettuato un altro montaggio. In
  tal caso infatti nella porzione di albero sotto \param{source} si troverebbe
  il contenuto del nuovo filesystem (o di un altro \textit{bind mount}) mentre
  sotto \param{target} ci sarebbe il contenuto presente nel filesystem
  originale.\footnote{questo evita anche il problema dei \textit{loop} di
    fig.~\ref{fig:file_link_loop}, dato che se anche si montasse su
    \param{target} una directory in cui essa è contenuta, il cerchio non
    potrebbe chiudersi perché ritornati a \param{target} dentro il
    \textit{bind mount} vi si troverebbe solo il contenuto originale e non si
    potrebbe tornare indietro.}

  Fino al kernel 2.6.26 questo flag doveva essere usato da solo, in quanto il
  \textit{bind mount} continuava ad utilizzare le stesse opzioni del montaggio
  originale, dal 2.6.26 è stato introdotto il supporto per il cosiddetto
  \textit{read-only bind mount} e viene onorata la presenza aggiuntiva del
  flag \const{MS\_RDONLY}. In questo modo si ottiene che l'accesso ai file
  sotto \param{target} sia effettuabile esclusivamente in sola lettura.

  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: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 collegamenti 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
  (introdotta a partire dai kernel della serie 2.6). L'opzione si applica a
  tutte le directory del filesystem, ma su alcuni filesystem è possibile
  impostarla a livello di singole directory o per i sottorami di una directory
  con il comando \cmd{chattr}.\footnote{questo avviene tramite delle opportune
    \texttt{ioctl} (vedi sez.~\ref{sec:file_ioctl}).}

  Questo consente di ridurre al minimo il rischio di perdita dei dati delle
  directory in caso di crollo improvviso del sistema, al costo di una certa
  perdita di prestazioni dato che le funzioni di scrittura relative ad
  operazioni sulle directory non saranno più bufferizzate e si bloccheranno
  fino all'arrivo dei dati sul disco prima che un programma possa proseguire.

\item[\const{MS\_MANDLOCK}] Consente l'uso del \textit{mandatory locking}
  \itindex{mandatory~locking} (vedi sez.~\ref{sec:file_mand_locking}) sui file
  del filesystem. Per poterlo utilizzare effettivamente però esso dovrà essere
  comunque attivato esplicitamente per i singoli file impostando i permessi
  come illustrato in sez.~\ref{sec:file_mand_locking}.

\item[\const{MS\_MOVE}] Effettua uno del spostamento del \itindex{mount~point}
  \textit{mount point} di un filesystem. La directory del
  \itindex{mount~point} \textit{mount point} originale deve essere indicata
  nell'argomento \param{source}, e la sua nuova posizione
  nell'argomento \param{target}. Tutti gli altri argomenti della funzione
  vengono ignorati.

  Lo spostamento avviene atomicamente, ed il ramo di albero presente
  sotto \param{source} sarà immediatamente visibile sotto \param{target}. Non
  esiste cioè nessun momento in cui il filesystem non risulti montato in una o
  nell'altra directory e pertanto è garantito che la risoluzione di
  \itindsub{pathname}{relativo} \textit{pathname} relativi all'interno del
  filesystem non possa fallire.

\item[\const{MS\_NOATIME}] Viene disabilitato sul filesystem l'aggiornamento
  degli \textit{access time} (vedi sez.~\ref{sec:file_file_times}) per
  qualunque tipo di file. Dato che l'aggiornamento degli \textit{access time}
  è una funzionalità la cui utilità è spesso irrilevante ma comporta un costo
  elevato visto che una qualunque lettura comporta comunque una scrittura su
  disco,\footnote{e questo ad esempio ha conseguenze molto pesanti nell'uso
    della batteria sui portatili.} questa opzione consente di disabilitarla
  completamente. La soluzione può risultare troppo drastica dato che
  l'informazione viene comunque utilizzata da alcuni programmi, per cui nello
  sviluppo del kernel sono state introdotte altre opzioni che forniscono
  soluzioni più appropriate e meno radicali.

\item[\const{MS\_NODEV}] Viene disabilitato sul filesystem l'accesso ai file
  di dispositivo eventualmente presenti su di esso. L'opzione viene usata come
  misura di precauzione per rendere inutile la presenza di eventuali file di
  dispositivo su filesystem che non dovrebbero contenerne.\footnote{si ricordi
    che le convenzioni del \itindex{Filesystem~Hierarchy~Standard~(FHS)}
    \textit{Linux Filesystem Hierarchy Standard} richiedono che questi siano
    mantenuti esclusivamente sotto \texttt{/dev}.}

  Viene utilizzata, assieme a \const{MS\_NOEXEC} e \const{MS\_NOSUID}, per
  fornire un accesso più controllato a quei filesystem di cui gli utenti hanno
  il controllo dei contenuti, in particolar modo quelli posti su dispositivi
  rimuovibili. In questo modo si evitano alla radice possibili situazioni in
  cui un utente malizioso inserisce su uno di questi filesystem dei file di
  dispositivo con permessi ``opportunamente'' ampliati che gli consentano di
  accedere anche a risorse cui non dovrebbe.

\item[\const{MS\_NODIRATIME}] Viene disabilitato sul filesystem
  l'aggiornamento degli \textit{access time} (vedi
  sez.~\ref{sec:file_file_times}), ma soltanto per le directory. Costituisce
  una alternativa per \const{MS\_NOATIME}, che elimina l'informazione per le
  directory, che in pratica che non viene mai utilizzata, mantenendola per i
  file in cui invece ha un impiego, sia pur limitato.

\item[\const{MS\_NOEXEC}] Viene disabilitata sul filesystem l'esecuzione di un
  qualunque file eseguibile eventualmente presente su di esso. L'opzione viene
  usata come misura di precauzione per rendere impossibile l'uso di programmi
  posti su filesystem che non dovrebbero contenerne.

  Anche in questo caso viene utilizzata per fornire un accesso più controllato
  a quei filesystem di cui gli utenti hanno il controllo dei contenuti. Da
  questo punto di vista l'opzione è meno importante delle analoghe
  \const{MS\_NODEV} e \const{MS\_NOSUID} in quanto l'esecuzione di un
  programma creato dall'utente pone un livello di rischio nettamente
  inferiore, ed è in genere consentita per i file contenuti nella sua home
  directory.\footnote{cosa che renderebbe superfluo l'attivazione di questa
    opzione, il cui uso ha senso solo per ambienti molto controllati in cui si
    vuole che gli utenti eseguano solo i programmi forniti
    dall'amministratore.}

\item[\const{MS\_NOSUID}] Viene disabilitato sul filesystem l'effetto dei bit
  dei permessi \itindex{suid~bit} \acr{suid} e \itindex{sgid~bit} \acr{sgid}
  (vedi sez.~\ref{sec:file_special_perm}) eventualmente presenti sui file in
  esso contenuti. L'opzione viene usata come misura di precauzione per rendere
  inefficace l'effetto di questi bit per filesystem in cui non ci dovrebbero
  essere file dotati di questi permessi.

  Di nuovo viene utilizzata, analogamente a \const{MS\_NOEXEC} e
  \const{MS\_NODEV}, per fornire un accesso più controllato a quei filesystem
  di cui gli utenti hanno il controllo dei contenuti. In questo caso si evita
  che un utente malizioso possa inserire su uno di questi filesystem un
  eseguibile con il bit \itindex{suid~bit} \acr{suid} attivo e di proprietà
  dell'amministratore o di un altro utente, che gli consentirebbe di eseguirlo
  per conto di quest'ultimo.

\item[\const{MS\_PRIVATE}] Marca un \itindex{mount~point} \textit{mount point}
  come privato. Si tratta di una delle nuove opzioni (insieme a
  \const{MS\_SHARED}, \const{MS\_SLAVE} e \const{MS\_UNBINDABLE}) facenti
  parte dell'infrastruttura degli \itindex{shared~subtree} \textit{shared
    subtree} introdotta a partire dal kernel 2.6.15, che estendono le
  funzionalità dei \itindex{bind~mount} \textit{bind mount}. In questo caso
  \param{target} dovrà fare riferimento al \textit{mount point} che si intende
  marcare, e tutti gli altri argomenti verranno ignorati.

  Di default, finché non lo si marca altrimenti con una delle altre opzioni
  dell'interfaccia \itindex{shared~subtree} \textit{shared subtree}, ogni
  \textit{mount point} è privato. Ogni \textit{bind mount} ottenuto da un
  \itindex{mount~point} \textit{mount point} di tipo \textit{private} si
  comporta come descritto nella trattazione di \const{MS\_BIND}. Si usa questo
  flag principalmente per revocare gli effetti delle altre opzioni e riportare
  il comportamento a quello ordinario.

\item[\const{MS\_RDONLY}] Esegue il montaggio del filesystem in sola lettura,
  non sarà possibile nessuna modifica ai suoi contenuti. Viene usato tutte le
  volte che si deve accedere ai contenuti di un filesystem con la certezza che
  questo non venga modificato (ad esempio per ispezionare un filesystem
  corrotto). All'avvio di default il kernel monta la radice in questa
  modalità.

\item[\const{MS\_REC}] Applica ricorsivamente a tutti i \itindex{mount~point}
  \textit{mount point} presenti al di sotto del \textit{mount point} indicato
  gli effetti della opzione degli \itindex{shared~subtree} \textit{shared
    subtree} associata. Anche questo caso l'argomento \param{target} deve fare
  riferimento ad un \itindex{mount~point} \textit{mount point} e tutti gli
  altri argomenti sono ignorati, ed il flag deve essere indicato assieme ad
  una fra \const{MS\_PRIVATE}, \const{MS\_SHARED}, \const{MS\_SLAVE} e
  \const{MS\_UNBINDABLE}.

\item[\const{MS\_RELATIME}] Indica di effettuare l'aggiornamento degli
  \textit{access time} sul filesystem soltanto quando questo risulti
  antecedente il valore corrente del \textit{modification time} o del
  \textit{change time} (per i tempi dei file si veda
  sez.~\ref{sec:file_file_times}). L'opzione è disponibile a partire dal
  kernel 2.6.20, mentre dal 2.6.30 questo è diventato il comportamento di
  default del sistema, che può essere riportato a quello tradizionale con
  l'uso di \const{MS\_STRICTATIME}. Sempre dal 2.6.30 il comportamento è stato
  anche modificato e l'\textit{access time} viene comunque aggiornato se è più
  vecchio di un giorno.

  L'opzione consente di evitare i problemi di prestazioni relativi
  all'aggiornamento dell'\textit{access time} senza avere impatti negativi
  riguardo le funzionalità, il comportamento adottato infatti consente di
  rendere evidente che vi è stato un accesso dopo la scrittura, ed evitando al
  contempo ulteriori operazioni su disco negli accessi successivi. In questo
  modo l'informazione relativa al fatto che un file sia stato letto resta
  disponibile, ed i programmi che ne fanno uso continuano a funzionare. Con
  l'introduzione di questo comportamento l'uso delle alternative
  \const{MS\_NOATIME} e \const{MS\_NODIRATIME} è sostanzialmente inutile.

\item[\const{MS\_REMOUNT}] Consente di rimontare un filesystem già montato
  cambiandone le opzioni di montaggio in maniera atomica. In questo modo si
  possono modificare le opzioni del filesystem anche se questo è in uso. Gli
  argomenti \param{source} e \param{target} devono essere gli stessi usati per
  il montaggio originale, mentre sia \param{data} che \param{mountflags}
  conterranno le nuove opzioni, \param{filesystemtype} viene ignorato.

  Qualunque opzione specifica del filesystem indicata con \param{data} può
  essere modificata, mentre con \param{mountflags} possono essere modificate
  solo alcune opzioni generiche. Con i kernel più recenti queste sono soltanto
  \const{MS\_MANDLOCK}, \const{MS\_RDONLY} e \const{MS\_SYNCHRONOUS}, prima
  del kernel 2.6.16 potevano essere modificate anche le ulteriori
  \const{MS\_NOATIME} e \const{MS\_NODIRATIME}, ed infine prima del kernel
  2.4.10 anche \const{MS\_NODEV}, \const{MS\_NOEXEC} e \const{MS\_NOSUID}.

\item[\const{MS\_SHARED}] Marca un \itindex{mount~point} \textit{mount point}
  come \textit{shared mount}.  Si tratta di una delle nuove opzioni (insieme a
  \const{MS\_PRIVATE}, \const{MS\_SLAVE} e \const{MS\_UNBINDABLE}) facenti
  parte dell'infrastruttura degli \itindex{shared~subtree} \textit{shared
    subtree} introdotta a partire dal kernel 2.6.15, che estendono le
  funzionalità dei \itindex{bind~mount} \textit{bind mount}.  In questo caso
  \param{target} dovrà fare riferimento al \itindex{mount~point} \textit{mount
    point} che si intende marcare, e tutti gli altri argomenti verranno
  ignorati.

  Lo scopo dell'opzione è ottenere che tutti i successivi \itindex{bind~mount}
  \textit{bind mount} effettuati da un \textit{mount point} marcato da essa
  siano di tipo \textit{shared}, cioè ``\textsl{condividano}'' con l'originale
  e fra di loro ogni ulteriore operazione di montaggio o smontaggio che
  avviene su una directory al di sotto di uno qualunque di essi. Le operazioni
  di montaggio e smontaggio effettuate al di sotto di un qualunque
  \textit{mount point} così marcato verranno ``\textsl{propagate}'' a tutti i
  \itindex{mount~point} \textit{mount point} della stessa condivisione, e la
  sezione di albero di file vista al di sotto di ciascuno di essi sarà sempre
  identica.

\item[\const{MS\_SILENT}] Richiede la soppressione di alcuni messaggi di
  avvertimento nei log del kernel (vedi sez.~\ref{sec:sess_daemon}). L'opzione
  è presente a partire dal kernel 2.6.17 e sostituisce, utilizzando un nome
  non fuorviante, la precedente \const{MS\_VERBOSE}, introdotta nel kernel
  2.6.12, che aveva lo stesso effetto.

\item[\const{MS\_SLAVE}] Marca un \itindex{mount~point} \textit{mount point}
  come \textit{slave mount}. Si tratta di una delle nuove opzioni (insieme a
  \const{MS\_PRIVATE}, \const{MS\_SHARED} e \const{MS\_UNBINDABLE}) facenti
  parte dell'infrastruttura degli \itindex{shared~subtree} \textit{shared
    subtree} introdotta a partire dal kernel 2.6.15, che estendono le
  funzionalità dei \itindex{bind~mount} \textit{bind mount}.  In questo caso
  \param{target} dovrà fare riferimento al \textit{mount point} che si intende
  marcare, e tutti gli altri argomenti verranno ignorati.

  Lo scopo dell'opzione è ottenere che tutti i successivi \textit{bind mount}
  effettuati da un \textit{mount point} marcato da essa siano di tipo
  \textit{slave}, cioè ``\textsl{condividano}'' ogni ulteriore operazione di
  montaggio o smontaggio che avviene su una directory al di sotto del
  \textit{mount point} originale. Le operazioni di montaggio e smontaggio in
  questo caso vengono ``\textsl{propagate}'' soltanto dal \textit{mount point}
  originale (detto anche \textit{master}) verso gli \textit{slave}, mentre
  essi potranno eseguire al loro interno ulteriori montaggi che non saranno
  propagati né negli altri né nel \itindex{mount~point} \textit{mount point}
  originale.

\item[\const{MS\_STRICTATIME}] Ripristina il comportamento tradizionale per
  cui l'\textit{access time} viene aggiornato ad ogni accesso al
  file. L'opzione è disponibile solo a partire dal kernel 2.6.30 quando il
  comportamento di default del kernel è diventato quello fornito da
  \const{MS\_RELATIME}.

\item[\const{MS\_SYNCHRONOUS}] Abilita la scrittura sincrona richiedendo che
  ogni modifica al contenuto del filesystem venga immediatamente registrata su
  disco. Lo stesso comportamento può essere ottenuto con il flag
  \const{O\_SYNC} di \func{open} (vedi sez.~\ref{sec:file_open}).

  Questa opzione consente di ridurre al minimo il rischio di perdita dei dati
  in caso di crollo improvviso del sistema, al costo di una pesante perdita di
  prestazioni dato che tutte le funzioni di scrittura non saranno più
  bufferizzate e si bloccheranno fino all'arrivo dei dati sul disco. Per un
  compromesso in cui questo comportamento avviene solo per le directory, ed ha
  quindi una incidenza nettamente minore, si può usare \const{MS\_DIRSYNC}.

\item[\const{MS\_UNBINDABLE}] Marca un \itindex{mount~point} \textit{mount
    point} come \textit{unbindable mount}. Si tratta di una delle nuove
  opzioni (insieme a \const{MS\_PRIVATE}, \const{MS\_SHARED} e
  \const{MS\_SLAVE}) facenti parte dell'infrastruttura degli
  \itindex{shared~subtree} \textit{shared subtree} introdotta a partire dal
  kernel 2.6.15, che estendono le funzionalità dei \itindex{bind~mount}
  \textit{bind mount}.  In questo caso
  \param{target} dovrà fare riferimento al \textit{mount point} che si intende
  marcare, e tutti gli altri argomenti verranno ignorati.

  Un \textit{mount point} marcato in questo modo disabilita la capacità di
  eseguire dei \itindex{bind~mount} \textit{bind mount} del suo contenuto. Si
  comporta cioè come allo stesso modo di un \itindex{mount~point}
  \textit{mount point} ordinario di tipo \textit{private} con in più la
  restrizione che nessuna sua sottodirectory (anche se relativa ad un
  ulteriore montaggio) possa essere utilizzata per un come sorgente di un
  \itindex{bind~mount} \textit{bind mount}.

\end{basedescript}

% NOTE per \const{MS\_SLAVE},\const{MS\_SHARE}, \const{MS\_PRIVATE} e
% \const{MS\_UNBINDABLE} dal 2.6.15 vedi shared subtrees, in particolare
%  * http://lwn.net/Articles/159077/ e
%  * Documentation/filesystems/sharedsubtree.txt

% TODO: (bassa priorità) non documentati ma presenti in sys/mount.h:
%       * MS_POSIXACL
%       * MS_KERNMOUNT
%       * MS_I_VERSION
%       * MS_ACTIVE
%       * MS_NOUSER


Una volta che non si voglia più utilizzare un certo filesystem è possibile
``\textsl{smontarlo}'' usando la funzione di sistema \funcd{umount}, il cui
prototipo è:

\begin{funcproto}{
\fhead{sys/mount.h}
\fdecl{umount(const char *target)}
\fdesc{Smonta un filesystem.} 
}
{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{EBUSY}] il filesystem è occupato.
  \item[\errcode{EINVAL}] \param{target} non è un \textit{mount point}.
  \item[\errcode{EPERM}] il processo non ha i privilegi di
    amministratore.\footnotemark 
  \end{errlist}
  ed inoltre \errval{EFAULT}, \errval{ELOOP}, \errval{ENAMETOOLONG},
  \errval{ENOENT}, \errval{ENOMEM} nel loro significato generico.  }
\end{funcproto}

\footnotetext{più precisamente la \itindex{capabilities} capacità
  \texttt{CAP\_SYS\_ADMIN}.}

La funzione prende il nome della directory su cui il filesystem è montato e
non il file o il dispositivo che è stato montato,\footnote{questo è vero a
  partire dal kernel 2.3.99-pre7, prima esistevano due chiamate separate e la
  funzione poteva essere usata anche specificando il file di dispositivo.} in
quanto a partire dai kernel della serie 2.4.x è possibile montare lo stesso
dispositivo in più punti. Nel caso più di un filesystem sia stato montato
sullo stesso \itindex{mount~point} \textit{mount point} viene smontato quello
che è stato montato per ultimo. Si tenga presente che la funzione fallisce se
il filesystem è ``\textsl{occupato}'', cioè quando ci sono ancora dei file
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 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}
\fdecl{umount2(const char *target, int flags)}
\fdesc{Smonta un filesystem.} 
}
{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{EBUSY}] \param{target} è la \index{directory~di~lavoro}
       directory di lavoro di qualche processo, o contiene dei file aperti, o un
       altro mount point.
     \item[\errcode{EAGAIN}] si è chiamata la funzione con \const{MNT\_EXPIRE}
       ed il filesystem non era occupato.
     \item[\errcode{EINVAL}] \param{target} non è un \itindex{mount~point}
       \textit{mount point} o si è usato \const{MNT\_EXPIRE} con
       \const{MNT\_FORCE} o \const{MNT\_DETACH} o si è specificato un flag non
       esistente.
  \end{errlist}
  e tutti gli altri valori visti per \func{umount} con lo stesso significato.}
\end{funcproto}

Il valore di \param{flags} è una maschera binaria dei flag che controllano le
modalità di smontaggio, che deve essere specificato con un OR aritmetico delle
costanti illustrate in tab.~\ref{tab:umount2_flags}.  Specificando
\const{MNT\_FORCE} la funzione cercherà di liberare il filesystem anche se è
occupato per via di una delle condizioni descritte in precedenza. A seconda
del tipo di filesystem alcune (o tutte) possono essere superate, evitando
l'errore di \errcode{EBUSY}. In tutti i casi prima dello smontaggio viene
eseguita una sincronizzazione dei dati.

\begin{table}[!htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|p{8cm}|}
    \hline
    \textbf{Costante} & \textbf{Descrizione}\\
    \hline
    \hline
    \const{MNT\_FORCE}  & forza lo smontaggio del filesystem anche se questo è
                          occupato (presente dai kernel della serie 2.2).\\
    \const{MNT\_DETACH} & esegue uno smontaggio ``\textsl{pigro}'', in cui si
                          blocca l'accesso ma si aspetta che il filesystem si
                          liberi (presente dal kernel 2.4.11 e dalla
                          \acr{glibc} 2.11).\\ 
    \const{MNT\_EXPIRE} & se non occupato marca un \itindex{mount~point} 
                          \textit{mount point} come ``\textsl{in scadenza}'' in
                          modo che ad una successiva chiamata senza utilizzo
                          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
                          collegamento 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}
    della funzione \func{umount2}.} 
  \label{tab:umount2_flags}
\end{table}

Con l'opzione \const{MNT\_DETACH} si richiede invece uno smontaggio
``\textsl{pigro}'' (o \textit{lazy umount}) in cui il filesystem diventa
inaccessibile per i nuovi processi subito dopo la chiamata della funzione, ma
resta accessibile per quelli che lo hanno ancora in uso e non viene smontato
fintanto che resta occupato.

Con \const{MNT\_EXPIRE}, che non può essere specificato insieme agli altri
due, si marca il \itindex{mount~point} \textit{mount point} di un filesystem
non occupato come ``\textsl{in scadenza}'', in tal caso \func{umount2} ritorna
con un errore di \errcode{EAGAIN}, mentre in caso di filesystem occupato si
sarebbe ricevuto \errcode{EBUSY}.  Una volta marcato, se nel frattempo non
viene fatto nessun uso del filesystem, ad una successiva chiamata con
\const{MNT\_EXPIRE} questo verrà smontato. Questo flag consente di realizzare
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 collegamento 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 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 privilegiati ma consentono di agire solo sui propri \textit{mount
  point}, dei collegamenti simbolici che puntano ad altri \textit{mount
  point}, ottenendo così la possibilità di smontare qualunque filesystem.


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}
\fdecl{int statfs(const char *path, struct statfs *buf)}
\fdecl{int fstatfs(int fd, struct statfs *buf)}
\fdesc{Restituiscono informazioni relative ad un filesystem.} 
}
{Le funzioni ritornano $0$ in caso di successo e $-1$ per un errore,
  nel qual caso \var{errno} assumerà uno dei valori: 
  \begin{errlist}
  \item[\errcode{ENOSYS}] il filesystem su cui si trova il file specificato
    non supporta la funzione.
  \end{errlist} ed inoltre \errval{EFAULT} ed \errval{EIO} per entrambe,
  \errval{EBADF} per \func{fstatfs}, \errval{ENOTDIR}, \errval{ENAMETOOLONG},
  \errval{ENOENT}, \errval{EACCES}, \errval{ELOOP} per \func{statfs} nel loro
  significato generico.}
\end{funcproto}

Queste funzioni permettono di ottenere una serie di informazioni generali
riguardo al filesystem su cui si trova il file specificato con un
\textit{pathname} per \func{statfs} e con un file descriptor (vedi
sez.~\ref{sec:file_fd}) per \func{statfs}.  Le informazioni vengono restituite
all'indirizzo \param{buf} di una struttura \struct{statfs} definita come in
fig.~\ref{fig:sys_statfs}, ed i campi che sono indefiniti per il filesystem in
esame sono impostati a zero.  I valori del campo \var{f\_type} sono definiti
per i vari filesystem nei relativi file di header dei sorgenti del kernel da
costanti del tipo \var{XXX\_SUPER\_MAGIC}, dove \var{XXX} in genere è il nome
del filesystem stesso.

\begin{figure}[!htb]
  \footnotesize \centering
  \begin{minipage}[c]{\textwidth}
    \includestruct{listati/statfs.h}
  \end{minipage}
  \normalsize 
  \caption{La struttura \structd{statfs}.} 
  \label{fig:sys_statfs}
\end{figure}

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},
  \funcm{getmntent},\funcm{getmntent\_r}, \funcm{addmntent},\funcm{endmntent},
  \funcm{hasmntopt}.} che convenzionalmente sono usati in quasi tutti i
sistemi unix-like per mantenere rispettivamente le informazioni riguardo ai
filesystem da montare e a quelli correntemente montati. Le funzioni servono a
leggere il contenuto di questi file in opportune strutture \struct{fstab} e
\struct{mntent}, e, nel caso di \conffile{/etc/mtab}, per inserire e rimuovere
le voci presenti nel file.

In generale si dovrebbero usare queste funzioni, in particolare quelle
relative a \conffile{/etc/mtab}, quando si debba scrivere un programma che
effettua il montaggio di un filesystem. In realtà in questi casi è molto più
semplice invocare direttamente il programma \cmd{mount}. Inoltre l'uso stesso
di \conffile{/etc/mtab} è considerato una pratica obsoleta, in quanto se non
aggiornato correttamente (cosa che è impossibile se la radice è montata in
sola lettura) il suo contenuto diventa fuorviante.

Per questo motivo il suo utilizzo viene deprecato ed in molti casi viene già
oggi sostituito da un collegamento 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 della \acr{glibc}
\cite{GlibcMan} per la documentazione completa.

% TODO (bassa priorità) scrivere delle funzioni (getfsent e getmntent &C)
% TODO (bassa priorità) documentare ? swapon e swapoff (man 2 ...) 


\section{La gestione di file e directory}
\label{sec:file_dir}

In questa sezione esamineremo le funzioni usate per la manipolazione dei nomi
file e directory, per la creazione di collegamenti 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}

Una caratteristica comune a diversi sistemi operativi è quella di poter creare
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 associata ad un puntatore che permette di
ottenere il riferimento ad un \itindex{inode} \textit{inode}, e che è
quest'ultimo che viene usato dal kernel per identificare univocamente gli
oggetti sul filesystem.

Questo significa che fintanto che si resta sullo stesso filesystem la
realizzazione di un \textit{link} è immediata: 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} e quindi
tutti otterranno lo stesso 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}
\fdecl{int link(const char *oldpath, const char *newpath)}
\fdesc{Crea un nuovo collegamento diretto (\textit{hard 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{EEXIST}] un file (o una directory) di nome \param{newpath}
    esiste già.
  \item[\errcode{EMLINK}] ci sono troppi collegamenti al file \param{oldpath}
    (il numero massimo è specificato dalla variabile \const{LINK\_MAX}, vedi
    sez.~\ref{sec:sys_limits}).
  \item[\errcode{EPERM}] il filesystem che contiene \param{oldpath} e
    \param{newpath} non supporta i collegamenti diretti o è una directory.
  \item[\errcode{EXDEV}] i file \param{oldpath} e \param{newpath} non fanno
    riferimento ad un filesystem montato sullo stesso \itindex{mount~point}
    \textit{mount point}.
  \end{errlist} ed inoltre \errval{EACCES}, \errval{EFAULT}, \errval{EIO},
  \errval{ELOOP}, \errval{ENAMETOOLONG}, \errval{ENOENT}, \errval{ENOMEM},
  \errval{ENOSPC}, \errval{ENOTDIR}, \errval{EROFS} nel loro significato
  generico.}
\end{funcproto}

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 la 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 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 fig.~\ref{fig:file_link_loop})
che molti programmi non sono in grado di gestire e la cui rimozione
diventerebbe piuttosto complicata.\footnote{in genere per questo tipo di
  errori occorre eseguire il programma \cmd{fsck} per riparare il filesystem,
  in quanto in caso di \textit{loop} la directory creata non sarebbe vuota e
  non si potrebbe più rimuoverla.}

Data la pericolosità di questa operazione e la disponibilità dei collegamenti
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 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
comportamento iniziale di Linux ma a partire dai kernel della serie
2.0.x\footnote{per la precisione il comportamento era quello previsto dallo
  standard POSIX fino al kernel di sviluppo 1.3.56, ed è stato temporaneamente
  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 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 conforme a questa versione
successiva dello standard.

\itindbeg{symbolic~link}

\index{collegamento!simbolico|(}

La ragione di questa differenza rispetto al vecchio standard, presente anche
in altri sistemi unix-like, è dovuta 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 \textit{link} 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 \itindex{inode}
  nell'\textit{inode} e riconoscibile dal valore del campo \var{st\_mode}
  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 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{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{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{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 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 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
  \begin{tabular}[c]{|l|c|c|}
    \hline
    \textbf{Funzione} & \textbf{Segue il link} & \textbf{Non segue il link} \\
    \hline 
    \hline 
    \func{access}   & $\bullet$ & --        \\
    \func{chdir}    & $\bullet$ & --        \\
    \func{chmod}    & $\bullet$ & --        \\
    \func{chown}    & --        & $\bullet$ \\
    \func{creat}    & $\bullet$ & --        \\
    \func{exec}     & $\bullet$ & --        \\
    \func{lchown}   & $\bullet$ & --        \\
    \func{link}\footnotemark & --        & $\bullet$ \\
    \func{lstat}    & --        & $\bullet$ \\
    \func{mkdir}    & $\bullet$ & --        \\
    \func{mkfifo}   & $\bullet$ & --        \\
    \func{mknod}    & $\bullet$ & --        \\
    \func{open}     & $\bullet$ & --        \\
    \func{opendir}  & $\bullet$ & --        \\
    \func{pathconf} & $\bullet$ & --        \\
    \func{readlink} & --        & $\bullet$ \\
    \func{remove}   & --        & $\bullet$ \\
    \func{rename}   & --        & $\bullet$ \\
    \func{stat}     & $\bullet$ & --        \\
    \func{truncate} & $\bullet$ & --        \\
    \func{unlink}   & --        & $\bullet$ \\
    \hline 
  \end{tabular}
  \caption{Uso dei 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.1-2001.}

Si noti che non si è specificato il comportamento delle funzioni che operano
con i file descriptor (che tratteremo nel prossimo capitolo), in quanto la
risoluzione del collegamento simbolico viene in genere effettuata dalla
funzione che restituisce il file descriptor (normalmente la \func{open}, vedi
sez.~\ref{sec:file_open}) e tutte le 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 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 collegamento simbolico
    o \param{size} non è positiva.
  \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 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 collegamento
    simbolico.}
  \label{fig:file_link_loop}
\end{figure}

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 \textit{loop} mostrato in
  fig.~\ref{fig:file_link_loop} è stato 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 vedrebbe 
  come \file{/}).}

Questo però può causare problemi per tutti quei programmi che effettuano la
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 fino ad un certo numero massimo 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}, 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}, se invece scrivessimo su \file{symlink}
otterremmo la creazione di \file{/tmp/tmp\_file} senza errori.


\itindend{symbolic~link}
\index{collegamento!simbolico|)}


Un'altra funzione relativa alla gestione dei nomi dei file, anche se a prima
vista parrebbe riguardare un argomento completamente diverso, è quella che per
la cancellazione di un file. In realtà una \textit{system call} 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 quella che si va a cancellare è soltanto la voce che
referenzia il suo \itindex{inode} \textit{inode} all'interno di una directory.

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:\footnotemark  
  \begin{errlist}
  \item[\errcode{EACCES}] non si ha il permesso di scrivere sulla directory
    contenente \param{pathname} o di attraversamento di una delle directory
    superiori. 
  \item[\errcode{EISDIR}] \param{pathname} si riferisce ad una
    directory.
  \item[\errcode{EPERM}] il filesystem non consente l'operazione, o la
    directory che contiene \param{pathname} ha lo \itindex{sticky~bit}
    \textit{sticky bit} e non si è il proprietario o non si hanno privilegi
    amministrativi. 
  \end{errlist} ed inoltre \errval{EFAULT}, \errval{EIO}, \errval{ELOOP},
  \errval{ENOENT}, \errval{ENOMEM}, \errval{ENOTDIR}, \errval{EROFS} nel loro
  significato generico.}
\end{funcproto}

\footnotetext{questa funzione su Linux ha alcune peculiarità nei codici di
  errore, in particolare riguardo la rimozione delle directory che non è mai
  permessa e che causa l'errore \errcode{EISDIR}; questo è un valore specifico
  di Linux 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, valore che invece Linux usa anche se il
  filesystem non supporta la funzione, inoltre il codice \errcode{EBUSY} nel
  caso la directory sia occupata su Linux non esiste.}

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}.\footnote{come per \func{link} queste due
  operazioni sono effettuate all'interno della \textit{system call} in maniera
  atomica.} 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.  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/attraversamento 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.

Si ricordi inoltre che anche se 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 e
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 può essere usata per essere sicuri di non
lasciare file temporanei su disco in caso di crash di un programma. La tecnica
è quella di aprire un nuovo file e chiamare \func{unlink} su di esso 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}),
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, nel qual caso si otterrebbe un
errore di \errcode{EISDIR}. Per cancellare una directory si deve 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 effettuare 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 un istante in cui un altro processo possa trovare attivi entrambi i
nomi per lo stesso file se la destinazione non esiste o in cui questa sparisca
temporaneamente se già esiste.

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'originale.

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 il kernel
assicura che esso non sarà toccato. I caso di sovrascrittura però potrà
esistere 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 una
sottodirectory di sé stessa, se questo fosse il caso si otterrebbe 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 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
  \itindex{Virtual~File~System} 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{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{EACCES}] non c'è il permesso di scrittura per la directory in
    cui si vuole inserire la nuova directory o di attraversamento per le
    directory al di sopra di essa.
  \item[\errcode{EEXIST}] un file o una directory o un collegamento simbolico
    con quel nome esiste già.
  \item[\errcode{EMLINK}] la directory in cui si vuole creare la nuova
    directory contiene troppi file; sotto Linux questo normalmente non avviene
    perché il filesystem standard consente la creazione di un numero di file
    maggiore di quelli che possono essere contenuti nel disco, ma potendo
    avere a che fare anche con filesystem di altri sistemi questo errore può
    presentarsi.
  \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 \errval{EFAULT}, \errval{ELOOP}, \errval{ENAMETOOLONG},
  \errval{ENOENT}, \errval{ENOMEM}, \errval{ENOTDIR}, \errval{EPERM},
  \errval{EROFS} nel loro significato generico.}
\end{funcproto}

La funzione crea una nuova directory vuota, che contiene cioè solo le due voci
standard presenti in ogni directory (``\file{.}'' e ``\file{..}''), con il
nome indicato dall'argomento \param{dirname}. 

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 illustrato in
sez.~\ref{sec:file_ownership_management}.

Come accennato in precedenza per eseguire la cancellazione di una directory è
necessaria una specifica funzione di sistema, \funcd{rmdir}, il suo prototipo
è:

\begin{funcproto}{
\fhead{sys/stat.h}
\fdecl{int rmdir(const char *dirname)}
\fdesc{Cancella 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{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{EINVAL}] si è usato ``\texttt{.}'' come ultimo componente
    di \param{dirname}.
  \item[\errcode{EBUSY}] la directory specificata è la
    \index{directory~di~lavoro} directory di lavoro o la radice di qualche
    processo o un \itindex{mount~point} \textit{mount point}.
  \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 non si è i
    proprietari della directory o non si hanno privilegi amministrativi. 
  \end{errlist}
  ed inoltre \errval{EFAULT}, \errval{ELOOP}, \errval{ENAMETOOLONG},
  \errval{ENOENT}, \errval{ENOMEM}, \errval{ENOTDIR}, \errcode{ENOTEMPTY} e
  \errval{EROFS} nel loro significato generico.}
\end{funcproto}


La funzione cancella la directory \param{dirname}, che deve essere vuota, la
directory deve cioè contenere le due voci standard ``\file{.}'' e
``\file{..}'' e niente altro.  Il nome può essere indicato con un
\textit{pathname} assoluto o relativo, ma si deve fare riferimento al nome
nella directory genitrice, questo significa che \textit{pathname} terminanti
in ``\file{.}'' e ``\file{..}'' anche se validi in altri contesti, causeranno
il fallimento della funzione.

Se la directory cancellata risultasse aperta in qualche processo per una
lettura dei suoi contenuti (vedi sez.~\ref{sec:file_dir_read}), pur
scomparendo dal filesystem e non essendo più possibile accedervi o crearvi
altri file, le risorse ad essa associate verrebbero disallocate solo alla
chiusura di tutti questi ulteriori riferimenti.


\subsection{Lettura e scansione delle directory}
\label{sec:file_dir_read}

Benché le directory alla fine non siano altro che dei file che contengono
delle liste di nomi associati ai relativi \itindex{inode} \textit{inode}, per
il ruolo che rivestono nella struttura del sistema non possono essere trattate
come dei normali file di dati. Ad esempio, onde evitare inconsistenze
all'interno del filesystem, solo il kernel può scrivere il contenuto di una
directory, e non può essere un processo a inserirvi direttamente delle voci
con le usuali funzioni di scrittura.

Ma se la scrittura e l'aggiornamento dei dati delle directory è compito del
kernel, sono molte le situazioni in cui i processi necessitano di poterne
leggere il contenuto. Benché questo possa essere fatto direttamente (vedremo
in sez.~\ref{sec:file_open} che è possibile aprire una directory come se fosse
un file, anche se solo in sola lettura) in generale il formato con cui esse
sono scritte può dipendere dal tipo di filesystem, tanto che, come riportato
in tab.~\ref{tab:file_file_operations}, il \itindex{Virtual~File~System} VFS
prevede una apposita funzione per la lettura delle directory.

\itindbeg{directory~stream}

Tutto questo si riflette nello standard POSIX\footnote{le funzioni erano
  presenti in SVr4 e 4.3BSD, la loro specifica è riportata in POSIX.1-2001.}
che ha introdotto una apposita interfaccia per la lettura delle directory,
basata sui cosiddetti \textit{directory stream}, chiamati così per l'analogia
con i \textit{file stream} dell'interfaccia standard ANSI C che vedremo in
cap.~\ref{cha:files_std_interface}. La prima funzione di questa interfaccia è
\funcd{opendir}, il cui prototipo è:

\begin{funcproto}{
\fhead{sys/types.h}
\fhead{dirent.h}
\fdecl{DIR *opendir(const char *dirname)}
\fdesc{Apre un \textit{directory stream}.} 
}
{La funzione ritorna un puntatore al \textit{directory stream} in caso di
  successo e \val{NULL} per un errore, nel qual caso \var{errno} assumerà uno
  dei valori \errval{EACCES}, \errval{EMFILE}, \errval{ENFILE},
  \errval{ENOENT}, \errval{ENOMEM} e \errval{ENOTDIR} nel loro significato
  generico.}
\end{funcproto}

La funzione apre un \textit{directory stream} per la directory
\param{dirname}, ritornando il puntatore ad un oggetto di tipo \type{DIR} (che
è il \index{tipo!opaco} tipo opaco usato dalle librerie per gestire i
\textit{directory stream}) da usare per tutte le operazioni successive, la
funzione inoltre posiziona lo \textit{stream} sulla prima voce contenuta nella
directory.

Si tenga presente che comunque la funzione opera associando il
\textit{directory stream} ad un opportuno file descriptor sottostante, sul
quale vengono compiute le operazioni. Questo viene sempre aperto impostando il
flag di \itindex{close-on-exec} \textit{close-on-exec} (si ricordi quanto
detto in sez.~\ref{sec:proc_exec}), così da evitare che resti aperto in caso
di esecuzione di un altro programma.

Nel caso in cui sia necessario conoscere il \textit{file descriptor} associato
ad un \textit{directory stream} si può usare la funzione
\funcd{dirfd},\footnote{questa funzione è una estensione introdotta con BSD
  4.3-Reno ed è presente in Linux con le libc5 (a partire dalla versione
  5.1.2) e con la \acr{glibc} ma non presente in POSIX fino alla revisione
  POSIX.1-2008, per questo per poterla utilizzare fino alla versione 2.10
  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 è:

\begin{funcproto}{
\fhead{sys/types.h}
\fhead{dirent.h}
\fdecl{int dirfd(DIR *dir)}
\fdesc{Legge il file descriptor associato ad un \textit{directory stream}.} 
}
{La funzione ritorna un valore positivo corrispondente al file descriptor in
  caso di successo e $-1$ per un errore, nel qual caso \var{errno} assumerà
  uno dei valori:
  \begin{errlist}
  \item[\errcode{EINVAL}] \param{dir} non è un puntatore ad un
    \textit{directory stream}. 
  \item[\errcode{ENOTSUP}] l'implementazione non supporta l'uso di un file
    descriptor per la directory.
  \end{errlist}
}
\end{funcproto}

La funzione restituisce il file descriptor associato al \textit{directory
  stream} \param{dir}. Di solito si utilizza questa funzione in abbinamento a
funzioni che operano sui file descriptor, ad esempio si potrà usare
\func{fstat} per ottenere le proprietà della directory, o \func{fchdir} per
spostare su di essa la \index{directory~di~lavoro} directory di lavoro (vedi
sez.~\ref{sec:file_work_dir}).

Viceversa se si è aperto un file descriptor corrispondente ad una directory è
possibile associarvi un \textit{directory stream} con la funzione
\funcd{fdopendir},\footnote{questa funzione è però disponibile solo a partire
  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
  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 è:

\begin{funcproto}{
\fhead{sys/types.h}
\fhead{dirent.h}
\fdecl{DIR *fdopendir(int fd)}
\fdesc{Associa un \textit{directory stream} ad un file descriptor.} 
}
{La funzione ritorna un puntatore al \textit{directory stream} in caso di
  successo e \val{NULL} per un errore, nel qual caso \var{errno} assumerà uno
  dei valori \errval{EBADF} o \errval{ENOMEM} nel loro significato generico.}
\end{funcproto}

La funzione è identica a \func{opendir}, ma ritorna un \textit{directory
  stream} facendo riferimento ad un file descriptor \param{fd} che deve essere
stato aperto in precedenza; la funzione darà un errore qualora questo non
corrisponda ad una directory. L'uso di questa funzione permette di rispondere
agli stessi requisiti delle funzioni ``\textit{at}'' che vedremo in
sez.~\ref{sec:file_openat}.

Una volta utilizzata il file descriptor verrà usato internamente dalle
funzioni che operano sul \textit{directory stream} e non dovrà essere più
utilizzato all'interno del proprio programma. In particolare dovrà essere
chiuso attraverso il \textit{directory stream} con \func{closedir} e non
direttamente. Si tenga presente inoltre che \func{fdopendir} non modifica lo
stato di un eventuale flag di \itindex{close-on-exec} \textit{close-on-exec},
che pertanto dovrà essere impostato esplicitamente in fase di apertura del
file descriptor.

Una volta che si sia aperto un \textit{directory stream} la lettura del
contenuto della directory viene effettuata attraverso la funzione
\funcd{readdir}, il cui prototipo è:

\begin{funcproto}{
\fhead{sys/types.h}
\fhead{dirent.h}
\fdecl{struct dirent *readdir(DIR *dir)}
\fdesc{Legge una voce dal \textit{directory stream}.} 
}
{La funzione ritorna il puntatore alla struttura contenente i dati in caso di
  successo e \val{NULL} per un errore o se si è raggiunta la fine dello
  \textit{stream}. Il solo codice di errore restituito in \var{errno} è
  \errval{EBADF} qualora \param{dir} non indichi un \textit{directory stream}
  valido.}
\end{funcproto}

La funzione legge la voce corrente nella directory, posizionandosi sulla voce
successiva. Pertanto se si vuole leggere l'intero contenuto di una directory
occorrerà ripetere l'esecuzione della funzione fintanto che non si siano
esaurite tutte le voci in essa presenti, che viene segnalata dalla
restituzione di \val{NULL} come valore di ritorno. Si può distinguere questa
condizione da un errore in quanto in questo caso \var{errno} non verrebbe
modificata.

I dati letti da \func{readdir} vengono memorizzati in una struttura
\struct{dirent}, la cui definizione è riportata in
fig.~\ref{fig:file_dirent_struct}.\footnote{la definizione è quella usata da
  Linux, che si trova nel file \file{/usr/include/bits/dirent.h}, essa non
  contempla la presenza del campo \var{d\_namlen} che indica la lunghezza del
  nome del file.} La funzione non è rientrante e restituisce il puntatore ad
una struttura allocata staticamente, che viene sovrascritta tutte le volte che
si ripete la lettura di una voce sullo stesso \textit{directory stream}.

Di questa funzione esiste anche una versione \index{funzioni!rientranti}
rientrante, \funcd{readdir\_r},\footnote{per usarla è necessario definire una
  qualunque delle macro \texttt{\macro{\_POSIX\_C\_SOURCE} >= 1},
  \macro{\_XOPEN\_SOURCE}, \macro{\_BSD\_SOURCE}, \macro{\_SVID\_SOURCE},
  \macro{\_POSIX\_SOURCE}.} che non usa una struttura allocata staticamente, e
può essere utilizzata anche con i \itindex{thread} \textit{thread}, il suo
prototipo è:

\begin{funcproto}{
\fhead{sys/types.h}
\fhead{dirent.h}
\fdecl{int readdir\_r(DIR *dir, struct dirent *entry, struct dirent **result)}
\fdesc{Legge una voce dal \textit{directory stream}.} 
}
{La funzione ritorna $0$ in caso di successo ed un numero positivo per un
  errore, nel qual caso \var{errno} assumerà gli stessi valori di
  \func{readdir}.} 
\end{funcproto}

La funzione restituisce in \param{result} come \itindex{value~result~argument}
\textit{value result argument} l'indirizzo della struttura \struct{dirent}
dove sono stati salvati i dati, che deve essere allocata dal chiamante, ed il
cui indirizzo deve essere indicato con l'argomento \param{entry}.  Se si è
raggiunta la fine del \textit{directory stream} invece in \param{result} viene
restituito il valore \val{NULL}.

\begin{figure}[!htb]
  \footnotesize \centering
  \begin{minipage}[c]{\textwidth}
    \includestruct{listati/dirent.c}
  \end{minipage} 
  \normalsize 
  \caption{La struttura \structd{dirent} per la lettura delle informazioni dei 
    file.}
  \label{fig:file_dirent_struct}
\end{figure}

% Lo spazio per la \struct{dirent} dove vengono restituiti i dati della
% directory deve essere allocato a cura del chiamante, dato che la dimensione


I vari campi di \struct{dirent} contengono le informazioni relative alle voci
presenti nella directory. Sia BSD che SVr4 che POSIX.1-2001\footnote{il
  vecchio standard POSIX prevedeva invece solo la presenza del campo
  \var{d\_fileno}, identico \var{d\_ino}, che in Linux era definito come alias
  di quest'ultimo, mentre il campo \var{d\_name} era considerato dipendente
  dall'implementazione.}  prevedono che siano sempre presenti il campo
\var{d\_name}, che contiene il nome del file nella forma di una stringa
terminata da uno zero, ed il campo \var{d\_ino}, che contiene il numero di
\itindex{inode} \textit{inode} cui il file è associato e corrisponde al campo
\var{st\_ino} di \struct{stat}.  La presenza di ulteriori campi opzionali
oltre i due citati è segnalata dalla definizione di altrettante macro nella
forma \code{\_DIRENT\_HAVE\_D\_XXX} dove \code{XXX} è il nome del relativo
campo. Come si può evincere da fig.~\ref{fig:file_dirent_struct} nel caso di
Linux sono pertanto definite le macro \macro{\_DIRENT\_HAVE\_D\_TYPE},
\macro{\_DIRENT\_HAVE\_D\_OFF} e \macro{\_DIRENT\_HAVE\_D\_RECLEN}, mentre non
è definita la macro \macro{\_DIRENT\_HAVE\_D\_NAMLEN}.

Dato che possono essere presenti campi opzionali e che lo standard
POSIX.1-2001 non specifica una dimensione definita per il nome dei file (che
può variare a seconda del filesystem), ma solo un limite superiore pari a
\const{NAME\_MAX} (vedi tab.~\ref{tab:sys_file_macro}), in generale per
allocare una struttura \struct{dirent} in maniera portabile occorre eseguire
un calcolo per ottenere le dimensioni appropriate per il proprio
sistema.\footnote{in SVr4 la lunghezza del campo è definita come
  \code{NAME\_MAX+1} che di norma porta al valore di 256 byte usato anche in
  fig.~\ref{fig:file_dirent_struct}.} Lo standard però richiede che il campo
\var{d\_name} sia sempre l'ultimo della struttura, questo ci consente di
ottenere la dimensione della prima parte con la macro di utilità generica
\macro{offsetof}, che si può usare con il seguente prototipo:

{\centering
\vspace{3pt}
\begin{funcbox}{
\fhead{stddef.h}
\fdecl{size\_t \macro{offsetof}(type, member)}
\fdesc{Restituisce la posizione del campo \param{member} nella
  struttura \param{type}.}
} 
\end{funcbox}
}

Ottenuta allora con \code{offsetof(struct dirent, d\_name)} la dimensione
della parte iniziale della struttura, basterà sommarci la dimensione massima
dei nomi dei file nel filesystem che si sta usando, che si può ottenere
attraverso la funzione \func{pathconf} (per la quale si rimanda a
sez.~\ref{sec:sys_pathconf}) più un ulteriore carattere per la terminazione
della stringa. 

Per quanto riguarda il significato dei campi opzionali, il campo \var{d\_type}
indica il tipo di file (se fifo, directory, collegamento simbolico, ecc.), e
consente di evitare una successiva chiamata a \func{lstat} (vedi
sez.~\ref{sec:file_stat}) 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 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}.}

\begin{table}[htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|l|}
    \hline
    \textbf{Valore} & \textbf{Tipo di file} \\
    \hline
    \hline
    \const{DT\_UNKNOWN} & Tipo sconosciuto.\\
    \const{DT\_REG}     & File normale.\\
    \const{DT\_DIR}     & Directory.\\
    \const{DT\_LNK}     & Collegamento simbolico.\\
    \const{DT\_FIFO}    & Fifo.\\
    \const{DT\_SOCK}    & Socket.\\
    \const{DT\_CHR}     & Dispositivo a caratteri.\\
    \const{DT\_BLK}     & Dispositivo a blocchi.\\
    \hline    
  \end{tabular}
  \caption{Costanti che indicano i vari tipi di file nel campo \var{d\_type}
    della struttura \struct{dirent}.}
  \label{tab:file_dtype_macro}
\end{table}

Per la conversione da e verso l'analogo valore mantenuto dentro il campo
\var{st\_mode} di \struct{stat} (vedi fig.~\ref{fig:file_stat_struct}) sono
definite anche due macro di conversione, \macro{IFTODT} e \macro{DTTOIF}:

{\centering
\vspace{3pt}
\begin{funcbox}{
\fhead{dirent.h}
\fdecl{int \macro{IFTODT}(mode\_t MODE)}
\fdesc{Converte il tipo di file dal formato di \var{st\_mode} a quello di
  \var{d\_type}.}
\fdecl{mode\_t \macro{DTTOIF}(int DTYPE)}
\fdesc{Converte il tipo di file dal formato di \var{d\_type} a quello di
  \var{st\_mode}.}  
} 
\end{funcbox}
}

Il campo \var{d\_off} contiene invece la posizione della voce successiva della
directory, mentre il campo \var{d\_reclen} la lunghezza totale della voce
letta. Con questi due campi diventa possibile, determinando la posizione delle
varie voci, spostarsi all'interno dello \textit{stream} usando la funzione
\funcd{seekdir},\footnote{sia questa funzione che \func{telldir}, sono
  estensioni prese da BSD, ed introdotte nello standard POSIX solo a partire
  dalla revisione POSIX.1-2001, per poterle utilizzare deve essere definita
  una delle macro \macro{\_XOPEN\_SOURCE}, \macro{\_BSD\_SOURCE} o
  \macro{\_SVID\_SOURCE}.} il cui prototipo è:

\begin{funcproto}{
\fhead{dirent.h}
\fdecl{void seekdir(DIR *dir, off\_t offset)}
\fdesc{Cambia la posizione all'interno di un \textit{directory stream}.} 
}
{La funzione non ritorna niente e non imposta errori.}
\end{funcproto}

La funzione non ritorna nulla e non segnala errori, è però necessario che il
valore dell'argomento \param{offset} sia valido per lo
\textit{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 cui prototipo
è:\footnote{prima 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{funcproto}{
\fhead{dirent.h}
\fdecl{long telldir(DIR *dir)}
\fdesc{Ritorna la posizione corrente in un \textit{directory stream}.} 
}
{La funzione ritorna la posizione corrente nello \textit{stream} (un numero
  positivo) in caso di successo e $-1$ per un errore, nel qual caso
  \var{errno} assume solo il valore di \errval{EBADF}, corrispondente ad un
  valore errato per \param{dir}.  }
\end{funcproto}

La sola funzione di posizionamento per un \textit{directory stream} prevista
originariamente dallo standard POSIX è \funcd{rewinddir}, che riporta la
posizione a quella iniziale; il suo prototipo è:

\begin{funcproto}{
\fhead{sys/types.h}
\fhead{dirent.h}
\fdecl{void rewinddir(DIR *dir)}
\fdesc{Si posiziona all'inizio di un \textit{directory stream}.} 
}
{La funzione non ritorna niente e non imposta errori.}
\end{funcproto}

Una volta completate le operazioni si può chiudere il \textit{directory
  stream}, ed il file descriptor ad esso associato, con la funzione
\funcd{closedir}, il cui prototipo è:

\begin{funcproto}{
\fhead{sys/types.h}
\fhead{dirent.h}
\fdecl{int closedir(DIR *dir)}
\fdesc{Chiude un \textit{directory stream}.} 
}
{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
  caso \var{errno} assume solo il valore \errval{EBADF}.}
\end{funcproto}

A parte queste funzioni di base in BSD 4.3 venne introdotta un'altra funzione
che permette di eseguire una scansione completa, con tanto di ricerca ed
ordinamento, del contenuto di una directory; la funzione è
\funcd{scandir}\footnote{in Linux questa funzione è stata introdotta fin dalle
  \acr{libc4} e richiede siano definite le macro \macro{\_BSD\_SOURCE} o
  \macro{\_SVID\_SOURCE}.} ed il suo prototipo è:

\begin{funcproto}{
\fhead{dirent.h}
\fdecl{int scandir(const char *dir, struct dirent ***namelist, \\
\phantom{int scandir(}int(*filter)(const struct dirent *), \\
\phantom{int scandir(}int(*compar)(const struct dirent **, const struct dirent **))}
\fdesc{Esegue una scansione di un \textit{directory stream}.} 
}
{La funzione ritorna il numero di voci trovate in caso di successo e $-1$ per
  un errore, nel qual caso \var{errno} può assumere solo il valore
  \errval{ENOMEM}.}
\end{funcproto}

Al solito, per la presenza fra gli argomenti di due puntatori a funzione, il
prototipo non è molto comprensibile; queste funzioni però sono quelle che
controllano rispettivamente la selezione di una voce, passata con
l'argomento \param{filter}, e l'ordinamento di tutte le voci selezionate,
specificata dell'argomento \param{compar}.

La funzione legge tutte le voci della directory indicata dall'argomento
\param{dir}, passando un puntatore a ciascuna di esse (una struttura
\struct{dirent}) come argomento della funzione di selezione specificata da
\param{filter}; se questa ritorna un valore diverso da zero il puntatore viene
inserito in un vettore che viene allocato dinamicamente con \func{malloc}.
Qualora si specifichi un valore \val{NULL} per l'argomento \param{filter} non
viene fatta nessuna selezione e si ottengono tutte le voci presenti.

Le voci selezionate possono essere riordinate tramite \funcm{qsort}, le
modalità del riordinamento possono essere personalizzate usando la funzione
\param{compar} come criterio di ordinamento di \funcm{qsort}, la funzione
prende come argomenti le due strutture \struct{dirent} da confrontare
restituendo un valore positivo, nullo o negativo per indicarne l'ordinamento;
alla fine l'indirizzo della lista ordinata dei puntatori alle strutture
\struct{dirent} viene restituito nell'argomento
\param{namelist}.\footnote{la funzione alloca automaticamente la lista, e
  restituisce, come \itindex{value~result~argument} \textit{value result
    argument}, l'indirizzo della stessa; questo significa che \param{namelist}
  deve essere dichiarato come \code{struct dirent **namelist} ed alla funzione
  si deve passare il suo indirizzo.}

\itindend{directory~stream}

Per l'ordinamento, vale a dire come valori possibili per l'argomento
\param{compar}, sono disponibili due funzioni predefinite, \funcd{alphasort} e
\funcd{versionsort}, i cui prototipi sono:

\begin{funcproto}{
\fhead{dirent.h}
\fdecl{int alphasort(const void *a, const void *b)}
\fdecl{int versionsort(const void *a, const void *b)}
\fdesc{Riordinano le voci di \textit{directory stream}.} 
}
{Le funzioni restituiscono un valore minore, uguale o maggiore di zero qualora
  il primo argomento sia rispettivamente minore, uguale o maggiore del secondo
  e non forniscono errori.}
\end{funcproto}

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}; 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. 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
  \begin{minipage}[c]{\codesamplewidth}
    \includecodesample{listati/my_ls.c}
  \end{minipage}
  \caption{Esempio di codice per eseguire la lista dei file contenuti in una
    directory.} 
  \label{fig:file_my_ls}
\end{figure}

Un semplice esempio dell'uso di queste funzioni è riportato in
fig.~\ref{fig:file_my_ls}, dove si è riportata la sezione principale di un
programma che, usando la funzione di scansione illustrata in
fig.~\ref{fig:file_dirscan}, stampa i nomi dei file contenuti in una directory
e la relativa dimensione, in sostanza una versione semplificata del comando
\cmd{ls}.

Il programma è estremamente semplice; in fig.~\ref{fig:file_my_ls} si è omessa
la parte di gestione delle opzioni, che prevede solo l'uso di una funzione per
la stampa della sintassi, anch'essa omessa, ma il codice completo può essere
trovato coi sorgenti allegati alla guida nel file \file{myls.c}.

In sostanza tutto quello che fa il programma, dopo aver controllato
(\texttt{\small 12--15}) di avere almeno un argomento, che indicherà la
directory da esaminare, è chiamare (\texttt{\small 16}) la funzione
\myfunc{dir\_scan} per eseguire la scansione, usando la funzione \code{do\_ls}
(\texttt{\small 22--29}) per fare tutto il lavoro.

Quest'ultima si limita (\texttt{\small 26}) a chiamare \func{stat} sul file
indicato dalla directory entry passata come argomento (il cui nome è appunto
\var{direntry->d\_name}), memorizzando in una opportuna struttura \var{data} i
dati ad esso relativi, per poi provvedere (\texttt{\small 27}) a stampare il
nome del file e la dimensione riportata in \var{data}.

Dato che la funzione verrà chiamata all'interno di \myfunc{dir\_scan} per ogni
voce presente questo è sufficiente a stampare la lista completa dei file e
delle relative dimensioni. Si noti infine come si restituisca sempre 0 come
valore di ritorno per indicare una esecuzione senza errori.

\begin{figure}[!htbp]
  \footnotesize \centering
  \begin{minipage}[c]{\codesamplewidth}
    \includecodesample{listati/dir_scan.c}
  \end{minipage}
  \caption{Codice della funzione di scansione di una directory contenuta nel
    file \file{dir\_scan.c}.} 
  \label{fig:file_dirscan}
\end{figure}

Tutto il grosso del lavoro è svolto dalla funzione \myfunc{dir\_scan},
riportata in fig.~\ref{fig:file_dirscan}. La funzione è volutamente generica e
permette di eseguire una funzione, passata come secondo argomento, su tutte le
voci di una directory.  La funzione inizia con l'aprire (\texttt{\small
  18--22}) uno \textit{stream} sulla directory passata come primo argomento,
stampando un messaggio in caso di errore.

Il passo successivo (\texttt{\small 23--24}) è cambiare
\index{directory~di~lavoro} directory di lavoro (vedi
sez.~\ref{sec:file_work_dir}), usando in sequenza le funzioni \func{dirfd} e
\func{fchdir} (in realtà si sarebbe potuto usare direttamente \func{chdir} su
\var{dirname}), in modo che durante il successivo ciclo (\texttt{\small
  26--30}) sulle singole voci dello \textit{stream} ci si trovi all'interno
della directory.\footnote{questo è essenziale al funzionamento della funzione
  \code{do\_ls}, e ad ogni funzione che debba usare il campo \var{d\_name}, in
  quanto i nomi dei file memorizzati all'interno di una struttura
  \struct{dirent} sono sempre relativi alla directory in questione, e senza
  questo posizionamento non si sarebbe potuto usare \func{stat} per ottenere
  le dimensioni.}

Avendo usato lo stratagemma di fare eseguire tutte le manipolazioni necessarie
alla funzione passata come secondo argomento, il ciclo di scansione della
directory è molto semplice; si legge una voce alla volta (\texttt{\small 26})
all'interno di una istruzione di \code{while} e fintanto che si riceve una
voce valida, cioè un puntatore diverso da \val{NULL}, si esegue
(\texttt{\small 27}) la funzione di elaborazione \var{compare} (che nel nostro
caso sarà \code{do\_ls}), ritornando con un codice di errore (\texttt{\small
  28}) qualora questa presenti una anomalia, identificata da un codice di
ritorno negativo. Una volta terminato il ciclo la funzione si conclude con la
chiusura (\texttt{\small 32}) dello \textit{stream}\footnote{nel nostro caso,
  uscendo subito dopo la chiamata, questo non servirebbe, in generale però
  l'operazione è necessaria, dato che la funzione può essere invocata molte
  volte all'interno dello stesso processo, per cui non chiudere i
  \textit{directory stream} comporterebbe un consumo progressivo di risorse,
  con conseguente rischio di esaurimento delle stesse.} e la restituzione
(\texttt{\small 32}) del codice di operazioni concluse con successo.



\subsection{La directory di lavoro}
\label{sec:file_work_dir}

\index{directory~di~lavoro|(} 

Come accennato in sez.~\ref{sec:proc_fork} a ciascun processo è associata una
directory nel filesystem,\footnote{questa viene mantenuta all'interno dei dati
  della sua \kstruct{task\_struct} (vedi fig.~\ref{fig:proc_task_struct}), più
  precisamente nel campo \texttt{pwd} della sotto-struttura
  \kstruct{fs\_struct}.} che è chiamata \textsl{directory corrente} o
\textsl{directory di lavoro} (in inglese \textit{current working directory}).
La directory di lavoro è quella da cui si parte quando un
\itindsub{pathname}{relativo} \textit{pathname} è espresso in forma relativa,
dove il ``\textsl{relativa}'' fa riferimento appunto a questa directory.

Quando un utente effettua il login, questa directory viene impostata alla
\textit{home directory} del suo account. Il comando \cmd{cd} della shell
consente di cambiarla a piacere, spostandosi da una directory ad un'altra, il
comando \cmd{pwd} la stampa sul terminale.  Siccome la directory di lavoro
resta la stessa quando viene creato un processo figlio (vedi
sez.~\ref{sec:proc_fork}), la directory di lavoro della shell diventa anche la
directory di lavoro di qualunque comando da essa lanciato.

Dato che è il kernel che tiene traccia per ciascun processo \itindex{inode}
dell'\textit{inode} della directory di lavoro, per ottenerne il
\textit{pathname} occorre usare una apposita funzione,
\funcd{getcwd},\footnote{con Linux \func{getcwd} è una \textit{system call}
  dalla versione 2.1.9, in precedenza il valore doveva essere ottenuto tramite
  il filesystem \texttt{/proc} da \procfile{/proc/self/cwd}.} il cui prototipo
è:

\begin{funcproto}{
\fhead{unistd.h}
\fdecl{char *getcwd(char *buffer, size\_t size)}
\fdesc{Legge il \textit{pathname} della directory di lavoro corrente.} 
}
{La funzione ritorna il puntatore a \param{buffer} in caso di successo e
  \val{NULL} per un errore, nel qual caso \var{errno} assumerà uno dei valori: 
  \begin{errlist}
  \item[\errcode{EACCES}] manca il permesso di lettura o di attraversamento  su
    uno dei componenti del \textit{pathname} (cioè su una delle directory
    superiori alla corrente).
  \item[\errcode{EINVAL}] l'argomento \param{size} è zero e \param{buffer} non
    è nullo.
  \item[\errcode{ENOENT}] la directory di lavoro è stata eliminata. 
  \item[\errcode{ERANGE}] l'argomento \param{size} è più piccolo della
    lunghezza del \textit{pathname}. 
  \end{errlist}
  ed inoltre \errcode{EFAULT} nel suo significato generico.}
\end{funcproto}

La funzione restituisce il \textit{pathname} completo della directory di
lavoro corrente nella stringa puntata da \param{buffer}, che deve essere
precedentemente allocata, per una dimensione massima di \param{size}.  Il
buffer deve essere sufficientemente largo da poter contenere il
\textit{pathname} completo più lo zero di terminazione della stringa. Qualora
esso ecceda le dimensioni specificate con \param{size} la funzione restituisce
un errore.

Si può anche specificare un puntatore nullo come
\param{buffer},\footnote{questa è un'estensione allo standard POSIX.1,
  supportata da Linux e dalla \acr{glibc}.} nel qual caso la stringa sarà
allocata automaticamente per una dimensione pari a \param{size} qualora questa
sia diversa da zero, o della lunghezza esatta del \textit{pathname}
altrimenti. In questo caso ci si deve ricordare di disallocare la stringa con
\func{free} una volta cessato il suo utilizzo.

Un uso comune di \func{getcwd} è quello di salvarsi la directory di lavoro
all'avvio del programma per poi potervi tornare in un tempo successivo, un
metodo alternativo più veloce, se non si è a corto di file descriptor, è
invece quello di aprire all'inizio la directory corrente (vale a dire
``\texttt{.}'') e tornarvi in seguito con \func{fchdir}.

Di questa funzione esiste una versione alternativa per compatibilità
all'indietro con BSD, \funcm{getwd}, che non prevede l'argomento \param{size}
e quindi non consente di specificare la dimensione di \param{buffer} che
dovrebbe essere allocato in precedenza ed avere una dimensione sufficiente
(per BSD maggiore \const{PATH\_MAX}, che di solito 256 byte, vedi
sez.~\ref{sec:sys_limits}). Il problema è che su Linux non esiste una
dimensione superiore per la lunghezza di un \textit{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 la tratteremo.

Una seconda funzione usata per ottenere la directory di lavoro è
\funcm{get\_current\_dir\_name},\footnote{la funzione è una estensione GNU e
  presente solo nella \acr{glibc}.} che non prende nessun argomento ed è
sostanzialmente equivalente ad una \code{getcwd(NULL, 0)}, con la differenza
che se disponibile essa ritorna il valore della variabile di ambiente
\envvar{PWD}, che essendo costruita dalla shell 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 collegamenti simbolici.

Per cambiare la directory di lavoro si può usare la funzione di sistema
\funcd{chdir}, equivalente del comando di shell \cmd{cd}, il cui nome sta
appunto per \textit{change directory}, il suo prototipo è:

\begin{funcproto}{
\fhead{unistd.h}
\fdecl{int chdir(const char *pathname)}
\fdesc{Cambia la directory di lavoro per \textit{pathname}.} 
}
{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{EACCES}] manca il permesso di ricerca su uno dei componenti
    di \param{pathname}.
  \item[\errcode{ENOTDIR}] non si è specificata una directory.
  \end{errlist}
  ed inoltre \errval{EFAULT}, \errval{ELOOP}, \errval{EIO},
  \errval{ENAMETOOLONG}, \errval{ENOENT} e \errval{ENOMEM} nel loro
  significato generico.}
\end{funcproto}

La funzione cambia la directory di lavoro in \param{pathname} ed
ovviamente \param{pathname} deve indicare una directory per la quale si hanno
i permessi di accesso.

Dato che ci si può riferire ad una directory anche tramite un file descriptor,
per cambiare directory di lavoro è disponibile anche la funzione di sistema
\funcd{fchdir}, il cui prototipo è:

\begin{funcproto}{
\fhead{unistd.h}
\fdecl{int fchdir(int fd)}
\fdesc{Cambia la directory di lavoro per file descriptor.} 
}
{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
  caso \var{errno} assumerà i valori \errval{EBADF} o \errval{EACCES} nel loro
  significato generico.}
\end{funcproto}

La funzione è identica a \func{chdir}, ma prende come argomento un file
descriptor \param{fd} invece di un \textit{pathname}. Anche in questo
caso \param{fd} deve essere un file descriptor valido che fa riferimento ad
una directory. Inoltre l'unico errore di accesso possibile (tutti gli altri
sarebbero occorsi all'apertura di \param{fd}), è quello in cui il processo non
ha il permesso di attraversamento alla directory specificata da \param{fd}.

\index{directory~di~lavoro|)} 


\subsection{La creazione dei \textsl{file speciali}}
\label{sec:file_mknod}

\index{file!di~dispositivo|(} 
\index{file!speciali|(} 

Finora abbiamo parlato esclusivamente di file, directory e collegamenti
simbolici, ma in sez.~\ref{sec:file_file_types} abbiamo visto che il sistema
prevede anche degli altri tipi di file, che in genere vanno sotto il nome
generico di \textsl{file speciali}, come i file di dispositivo, le fifo ed i
socket.

La manipolazione delle caratteristiche di questi file speciali, il cambiamento
di nome o la loro cancellazione può essere effettuata con le stesse funzioni
che operano sugli altri file, ma quando li si devono creare sono necessarie,
come per le directory, delle funzioni apposite. La prima di queste è la
funzione di sistema \funcd{mknod}, il cui prototipo è:

\begin{funcproto}{
\fhead{sys/types.h}
\fhead{sys/stat.h}
\fhead{fcntl.h}
\fhead{unistd.h}
\fdecl{int mknod(const char *pathname, mode\_t mode, dev\_t dev)}
\fdesc{Crea un file speciale sul filesystem.} 
}
{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}] \param{pathname} esiste già o è un collegamento
    simbolico. 
  \item[\errcode{EINVAL}] il valore di \param{mode} non indica un file, una
    fifo, un socket o un dispositivo.
  \item[\errcode{EPERM}] non si hanno privilegi sufficienti a creare
    \itindex{inode} l'\texttt{inode}, o il filesystem su cui si è cercato di
    creare \param{pathname} non supporta l'operazione.
  \end{errlist}
  ed inoltre \errval{EACCES}, \errval{EFAULT}, \errval{ELOOP},
  \errval{ENAMETOOLONG}, \errval{ENOENT}, \errval{ENOMEM}, \errval{ENOSPC},
  \errval{ENOTDIR} e \errval{EROFS} nel loro significato generico.}
\end{funcproto}

La funzione permette di creare un \itindex{inode} \textit{inode} di tipo
generico sul filesystem, e viene in genere utilizzata per creare i file di
dispositivo, ma si può usare anche per creare qualunque tipo di file speciale
ed anche 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 aritmetico. 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 collegamenti simbolici, si dovranno usare le funzioni
  \func{mkdir} e \func{symlink} a questo dedicate.} un valore diverso
comporterà l'errore \errcode{EINVAL}. Inoltre \param{pathname} non deve
esistere, neanche come collegamento simbolico.

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 (usando \ids{UID} e \ids{GID} del
gruppo effettivo) che li ha creati a meno non sia presente 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}, nel qual caso per il gruppo verrà usato il
\ids{GID} del proprietario della directory.

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 uno dei dischi presenti) 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
comportato il fatto che \type{dev\_t} è diventato un \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},\footnote{se si usa
  la \acr{glibc} dalla versione 2.3.3 queste macro sono degli alias alle
  versioni specifiche di questa libreria, \macro{gnu\_dev\_major},
  \macro{gnu\_dev\_minor} e \macro{gnu\_dev\_makedev} che si possono usare
  direttamente, al costo di una minore portabilità.} 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}:

{\centering
\vspace{3pt}
\begin{funcbox}{
\fhead{sys/types.h}
\fdecl{int \macro{major}(dev\_t dev)}
\fdesc{Restituisce il \itindex{major~number} \textit{major number} del
  dispositivo \param{dev}.}
\fdecl{int \macro{minor}(dev\_t dev)}
\fdesc{Restituisce il \itindex{minor~number} \textit{minor number} del
  dispositivo \param{dev}.}  
} 
\end{funcbox}
}

\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}:

{\centering
\vspace{3pt}
\begin{funcbox}{
\fhead{sys/types.h}
\fdecl{dev\_t \macro{makedev}(int major, int minor)}
\fdesc{Dati \itindex{major~number} \textit{major number} e
  \itindex{minor~number} \textit{minor number} restituisce l'identificativo di
  un dispositivo.} 
} 
\end{funcbox}
}

\index{file!di~dispositivo|)}

Dato che la funzione di sistema \func{mknod} presenta diverse varianti nei
vari sistemi unix-like, lo standard POSIX.1-2001 la dichiara portabile solo in
caso di creazione delle fifo, ma anche in questo caso alcune combinazioni
degli argomenti restano non specificate, per cui nello stesso standard è stata
introdotta una funzione specifica per creare una fifo deprecando l'uso di
\func{mknod} a tale riguardo.  La funzione è \funcd{mkfifo} ed il suo
prototipo è:

\begin{funcproto}{
\fhead{sys/types.h}
\fhead{sys/stat.h}
\fdecl{int mkfifo(const char *pathname, mode\_t mode)}
\fdesc{Crea una fifo.} 
}
{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
  caso \var{errno} assumerà \errval{EACCES}, \errval{EEXIST},
  \errval{ENAMETOOLONG}, \errval{ENOENT}, \errval{ENOSPC}, \errval{ENOTDIR} e
  \errval{EROFS} nel loro significato generico.}
\end{funcproto}

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
collegamento simbolico); al solito i permessi specificati da \param{mode}
vengono modificati dal valore di \itindex{umask} \textit{umask}.

\index{file!speciali|)} 


\subsection{I file temporanei}
\label{sec:file_temp_file}

In molte occasioni è utile poter creare dei file temporanei; benché la cosa
sembri semplice, in realtà il problema è più sottile di quanto non appaia a
prima vista. Infatti anche se sembrerebbe banale generare un nome a caso e
creare il file dopo aver controllato che questo non esista, nel momento fra il
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}).

Molti problemi di sicurezza derivano proprio da una creazione non accorta di
file temporanei che lascia aperta questa \itindex{race~condition} \textit{race
  condition}. Un attaccante allora potrà sfruttarla con quello che viene
chiamato ``\textit{symlink attack}'' dove nell'intervallo fra la generazione
di un nome e l'accesso allo stesso, viene creato un collegamento simbolico con
quel nome verso un file diverso, ottenendo, se il programma sotto attacco ne
ha la capacità, un accesso privilegiato.

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
  POSIX.1-2008 dello standard POSIX.} il cui prototipo è:

\begin{funcproto}{
\fhead{stdio.h}
\fdecl{char *tmpnam(char *string)}
\fdesc{Genera un nome univoco per un file temporaneo.} 
}
{La funzione ritorna il puntatore alla stringa con il nome in caso di successo
  e \val{NULL} in caso di fallimento, non sono definiti errori.}
\end{funcproto}

La funzione restituisce il puntatore ad una stringa contente un nome di file
valido e non esistente al momento dell'invocazione; se si è passato come
argomento \param{string} un puntatore non nullo ad un buffer di caratteri
questo deve essere di dimensione \const{L\_tmpnam} ed il nome generato vi
verrà copiato automaticamente; altrimenti il nome sarà generato in un buffer
statico interno che verrà sovrascritto ad una chiamata successiva.  Successive
invocazioni della funzione continueranno a restituire nomi unici fino ad un
massimo di \const{TMP\_MAX} volte, limite oltre il quale il comportamento è
indefinito. Al nome viene automaticamente aggiunto come prefisso la directory
specificata dalla costante \const{P\_tmpdir}.\footnote{le costanti
  \const{L\_tmpnam}, \const{P\_tmpdir} e \const{TMP\_MAX} sono definite in
  \headfile{stdio.h}.}

Di questa funzione esiste una versione \index{funzioni!rientranti} rientrante,
\funcm{tmpnam\_r}, che non fa nulla quando si passa \val{NULL} come argomento.
Una funzione simile, \funcd{tempnam}, permette di specificare un prefisso per
il file esplicitamente, il suo prototipo è:

\begin{funcproto}{
\fhead{stdio.h}
\fdecl{char *tempnam(const char *dir, const char *pfx)}
\fdesc{Genera un nome univoco per un file temporaneo.} 
}
{La funzione ritorna il puntatore alla stringa con il nome in caso di successo
  e \val{NULL} per un errore, nel qual caso \var{errno} potrà assumere solo il
  valore \errval{ENOMEM} qualora fallisca l'allocazione della stringa.}
\end{funcproto}

La funzione alloca con \code{malloc} la stringa in cui restituisce il nome,
per cui è sempre \index{funzioni!rientranti} rientrante, occorre però
ricordarsi di disallocare con \code{free} il puntatore che restituisce.
L'argomento \param{pfx} specifica un prefisso di massimo 5 caratteri per il
nome provvisorio. La funzione assegna come directory per il file temporaneo,
verificando che esista e sia accessibile, la prima valida fra le seguenti:
\begin{itemize*}
\item La variabile di ambiente \envvar{TMPDIR} (non ha effetto se non è
  definita o se il programma chiamante è \itindex{suid~bit} \acr{suid} o
  \itindex{sgid~bit} \acr{sgid}, vedi sez.~\ref{sec:file_special_perm}).
\item il valore dell'argomento \param{dir} (se diverso da \val{NULL}).
\item Il valore della costante \const{P\_tmpdir}.
\item la directory \file{/tmp}.
\end{itemize*}

In ogni caso, anche se con queste funzioni la generazione del nome è casuale,
ed è molto difficile ottenere un nome duplicato, nulla assicura che un altro
processo non possa avere creato, fra l'ottenimento del nome e l'apertura del
file, un altro file o un collegamento simbolico con lo stesso nome. Per questo
motivo quando si usa il nome ottenuto da una di queste funzioni occorre sempre
assicurarsi che non si stia usando un collegamento simbolico e aprire il nuovo
file in modalità di esclusione (cioè con l'opzione \const{O\_EXCL} per i file
descriptor o con il flag \code{x} per gli \textit{stream}) che fa fallire
l'apertura in caso il file sia già esistente. Essendo disponibili alternative
migliori l'uso di queste funzioni è deprecato.

Per evitare di dovere effettuare a mano tutti questi controlli, lo standard
POSIX definisce la funzione \funcd{tmpfile}, che permette di ottenere in
maniera sicura l'accesso ad un file temporaneo, il suo prototipo è:

\begin{funcproto}{
\fhead{stdio.h}
\fdecl{FILE *tmpfile(void)}
\fdesc{Apre un file temporaneo in lettura/scrittura.} 
}
{La funzione ritorna il puntatore allo \textit{stream} associato al file
  temporaneo in caso di successo e \val{NULL} per un errore, nel qual caso
  \var{errno} assumerà uno dei valori:
  \begin{errlist}
    \item[\errcode{EEXIST}] non è stato possibile generare un nome univoco.
    \item[\errcode{EINTR}] la funzione è stata interrotta da un segnale.
  \end{errlist}
  ed inoltre \errval{EFAULT}, \errval{EMFILE}, \errval{ENFILE},
  \errval{ENOSPC}, \errval{EROFS} e \errval{EACCES} nel loro significato
  generico.}
\end{funcproto}


La funzione restituisce direttamente uno \textit{stream} già aperto (in
modalità \code{w+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 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}.

Alcune versioni meno recenti di Unix non supportano queste funzioni; in questo
caso si possono usare le vecchie funzioni \funcd{mktemp} e \func{mkstemp} che
modificano una stringa di input che serve da modello e che deve essere
conclusa da 6 caratteri ``\texttt{X}'' che verranno sostituiti da un codice
unico. La prima delle due è analoga a \func{tmpnam} e genera un nome casuale,
il suo prototipo è:

\begin{funcproto}{
\fhead{stlib.h}
\fdecl{char *mktemp(char *template)}
\fdesc{Genera un nome univoco per un file temporaneo.} 
}
{La funzione ritorna  il puntatore a \param{template} in caso di successo e
  \val{NULL} per un errore, nel qual caso \var{errno} assumerà uno dei valori: 
  \begin{errlist}
    \item[\errcode{EINVAL}] \param{template} non termina con \code{XXXXXX}.
  \end{errlist}}
\end{funcproto}

La funzione genera un nome univoco sostituendo le \code{XXXXXX} finali di
\param{template}; dato che \param{template} deve poter essere modificata dalla
funzione non si può usare una stringa costante.  Tutte le avvertenze riguardo
alle possibili \itindex{race~condition} \textit{race condition} date per
\func{tmpnam} continuano a valere; inoltre in alcune vecchie implementazioni
il valore usato per sostituire le \code{XXXXXX} viene formato con il \ids{PID}
del processo più una lettera, il che mette a disposizione solo 26 possibilità
diverse per il nome del file, e rende il nome temporaneo facile da indovinare.
Per tutti questi motivi la funzione è deprecata e non dovrebbe mai essere
usata.

La seconda funzione, \funcd{mkstemp} è sostanzialmente equivalente a
\func{tmpfile}, ma restituisce un file descriptor invece di un nome; il suo
prototipo è:

\begin{funcproto}{
\fhead{stlib.h}
\fdecl{int mkstemp(char *template)}
\fdesc{Apre un file temporaneo.} 
}

{La funzione ritorna il file descriptor in caso di successo e $-1$ per un
  errore, nel qual 
  caso \var{errno} assumerà uno dei valori: 
  \begin{errlist}
    \item[\errcode{EINVAL}] \param{template} non termina con \code{XXXXXX}.
    \item[\errcode{EEXIST}] non è riuscita a creare un file temporaneo, il
      contenuto di \param{template} è indefinito.
  \end{errlist}}
\end{funcproto}


Come per \func{mktemp} anche in questo caso \param{template} non può essere
una stringa costante. La funzione apre un file in lettura/scrittura con la
funzione \func{open}, usando l'opzione \const{O\_EXCL} (si veda
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 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
specificamente dalla \acr{glibc},\footnote{la funzione è stata introdotta
  nella versione 2.7 delle librerie e richiede che sia definita la macro
  \macro{\_GNU\_SOURCE}.} il cui prototipo è:

\begin{funcproto}{
\fhead{stlib.h}
\fdecl{int mkostemp(char *template, int flags)}
\fdesc{Apre un file temporaneo.} 
}
{La funzione ritorna un file descriptor in caso di successo e $-1$ per un
  errore, nel qual caso \var{errno} assumerà  gli stessi valori di
  \func{mkstemp}.} 
\end{funcproto}
\noindent la cui sola differenza è la presenza dell'ulteriore argomento
\var{flags} che consente di specificare i flag da passare ad \func{open}
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 nella \acr{glibc} a partire dalla versione
  2.1.91 ed inserita nello standard POSIX.1-2008.}  il suo prototipo è:

\begin{funcproto}{
\fhead{stlib.h}
\fdecl{char *mkdtemp(char *template)}
\fdesc{Crea una directory temporanea.} 
}
{La funzione ritorna il puntatore al nome della directory in caso di successo
  e \val{NULL} per un errore, nel qual caso \var{errno} assumerà uno dei
  valori:
  \begin{errlist}
    \item[\errcode{EINVAL}] \param{template} non termina con \code{XXXXXX}.
  \end{errlist}
  più gli altri eventuali codici di errore di \func{mkdir}.}
\end{funcproto}

La funzione genera una directory il cui nome è ottenuto sostituendo le
\code{XXXXXX} finali di \param{template} con permessi \code{0700} (al solito
si veda cap.~\ref{cha:file_unix_interface} per i dettagli); dato che la
creazione della directory è sempre esclusiva i precedenti problemi di
\itindex{race~condition} \textit{race condition} non si pongono.





\section{La manipolazione delle caratteristiche dei file}
\label{sec:file_infos}

Come spiegato in sez.~\ref{sec:file_filesystem} tutte le informazioni generali
relative alle caratteristiche di ciascun file, a partire dalle informazioni
relative al controllo di accesso, sono mantenute \itindex{inode}
nell'\textit{inode}. Vedremo in questa sezione come sia possibile leggere
tutte queste informazioni usando la funzione \func{stat}, che permette
l'accesso a tutti i dati memorizzati \itindex{inode} nell'\textit{inode};
esamineremo poi le varie funzioni usate per manipolare tutte queste
informazioni, eccetto quelle che riguardano la gestione del controllo di
accesso, trattate in in sez.~\ref{sec:file_access_control}.


\subsection{La lettura delle caratteristiche dei file}
\label{sec:file_stat}

La lettura delle informazioni relative ai file è fatta attraverso la famiglia
delle funzioni \func{stat} che sono quelle che usa il comando \cmd{ls} per
poter ottenere e mostrare tutti i dati relativi ad un file; ne fanno parte le
funzioni di sistema \funcd{stat}, \funcd{fstat} e \funcd{lstat}, i cui
prototipi sono:

\begin{funcproto}{
\fhead{sys/types.h}
\fhead{sys/stat.h}
\fhead{unistd.h}
\fdecl{int stat(const char *file\_name, struct stat *buf)}
\fdecl{int lstat(const char *file\_name, struct stat *buf)}
\fdecl{int fstat(int filedes, struct stat *buf)}
\fdesc{Leggono le informazioni di un file.} 
}
{Le funzioni ritornano $0$ in caso di successo e $-1$ per un errore, nel qual
  caso \var{errno} assumerà uno dei valori:
  \begin{errlist}
    \item[\errcode{EOVERFLOW}] il file ha una dimensione che non può essere
      rappresentata nel tipo \type{off\_t} (può avvenire solo in caso di
      programmi compilati su piattaforme a 32 bit senza le estensioni
      (\texttt{-D \_FILE\_OFFSET\_BITS=64}) per file a 64 bit).
  \end{errlist}
  ed inoltre \errval{EFAULT} ed \errval{ENOMEM}, per \func{stat} e
  \func{lstat} anche \errval{EACCES}, \errval{ELOOP}, \errval{ENAMETOOLONG},
  \errval{ENOENT}, \errval{ENOTDIR}, per \func{fstat} anche \errval{EBADF}, 
  nel loro significato generico.}
\end{funcproto}

La funzione \func{stat} legge le informazioni del file indicato
da \param{file\_name} e le inserisce nel buffer puntato
dall'argomento \param{buf}; la funzione \func{lstat} è identica a \func{stat}
eccetto che se \param{file\_name} è un collegamento simbolico vengono lette le
informazioni relative ad esso e non al file a cui fa riferimento. Infine
\func{fstat} esegue la stessa operazione su un file già aperto, specificato
tramite il suo file descriptor \param{filedes}.

La struttura \struct{stat} usata da queste funzioni è definita nell'header
\headfile{sys/stat.h} e in generale dipende dall'implementazione; la versione
usata da Linux è mostrata in fig.~\ref{fig:file_stat_struct}, così come
riportata dalla pagina di manuale di \func{stat}. In realtà la definizione
effettivamente usata nel kernel dipende dall'architettura e ha altri campi
riservati per estensioni come tempi dei file più precisi (vedi
sez.~\ref{sec:file_file_times}).

\begin{figure}[!htb]
  \footnotesize
  \centering
  \begin{minipage}[c]{\textwidth}
    \includestruct{listati/stat.h}
  \end{minipage} 
  \normalsize 
  \caption{La struttura \structd{stat} per la lettura delle informazioni dei 
    file.}
  \label{fig:file_stat_struct}
\end{figure}

Si noti come i vari membri della struttura siano specificati come tipi
primitivi del sistema, di quelli definiti in
tab.~\ref{tab:intro_primitive_types}, e dichiarati in \headfile{sys/types.h},
con l'eccezione di \type{blksize\_t} e \type{blkcnt\_t} che sono nuovi tipi
introdotti per rendersi indipendenti dalla piattaforma. 

Benché la descrizione dei commenti di fig.~\ref{fig:file_stat_struct} sia
abbastanza chiara, vale la pena illustrare maggiormente il significato dei
campi di \structd{stat} su cui non torneremo in maggior dettaglio nel resto di
questa sezione:
\begin{itemize*}

\item Il campo \var{st\_nlink} contiene il numero di \textit{hard link} che
  fanno riferimento al file (il cosiddetto \textit{link count}) di cui abbiamo
  già parlato in numerose occasioni.

\item Il campo \var{st\_ino} contiene il numero di \itindex{inode}
  \textit{inode} del file, quello viene usato all'interno del filesystem per
  identificarlo e che può essere usato da un programma per determinare se due
  \textit{pathname} fanno riferimento allo stesso file.

\item Il campo \var{st\_dev} contiene il numero del dispositivo su cui risiede
  il file (o meglio il suo filesystem). Si tratta dello stesso numero che si
  usa con \func{mknod} e che può essere decomposto in \itindex{major~number}
  \textit{major number} e \itindex{minor~number} \textit{minor number} con le
  macro \macro{major} e \macro{minor} viste in sez.~\ref{sec:file_mknod}.

\item Il campo \var{st\_rdev} contiene il numero di dispositivo associato al
  file stesso ed ovviamente ha un valore significativo soltanto quando il file
  è un dispositivo a caratteri o a blocchi.

\item Il campo \var{st\_blksize} contiene la dimensione dei blocchi di dati
  usati nell'I/O su disco, che è anche la dimensione usata per la
  bufferizzazione dei dati dalle librerie del C per l'interfaccia degli
  \textit{stream}.  Leggere o scrivere blocchi di dati in dimensioni inferiori
  a questo valore è inefficiente in quanto le operazioni su disco usano
  comunque trasferimenti di questa dimensione.

\end{itemize*}



\subsection{I tipi di file}
\label{sec:file_types}

Abbiamo sottolineato fin dall'introduzione che Linux, come ogni sistema
unix-like, supporta oltre ai file ordinari e alle directory una serie di altri
``\textsl{tipi}'' di file che possono stare su un filesystem (elencati in
tab.~\ref{tab:file_file_types}).  Il tipo di file viene ritornato dalle
funzioni della famiglia \func{stat} all'interno del campo \var{st\_mode} di
una struttura \struct{stat}. 

Il campo \var{st\_mode} è una maschera binaria in cui l'informazione viene
suddivisa nei vari bit che compongono, ed oltre a quelle sul tipo di file,
contiene anche le informazioni relative ai permessi su cui torneremo in
sez.~\ref{sec:file_perm_overview}. Dato che i valori numerici usati per
definire il tipo di file possono variare a seconda delle implementazioni, lo
standard POSIX definisce un insieme di macro che consentono di verificare il
tipo di file in maniera standardizzata.

\begin{table}[htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|l|}
    \hline
    \textbf{Macro} & \textbf{Tipo del file} \\
    \hline
    \hline
    \macro{S\_ISREG}\texttt{(m)}  & file normale.\\
    \macro{S\_ISDIR}\texttt{(m)}  & directory.\\
    \macro{S\_ISCHR}\texttt{(m)}  & dispositivo a caratteri.\\
    \macro{S\_ISBLK}\texttt{(m)}  & dispositivo a blocchi.\\
    \macro{S\_ISFIFO}\texttt{(m)} & fifo.\\
    \macro{S\_ISLNK}\texttt{(m)}  & collegamento simbolico.\\
    \macro{S\_ISSOCK}\texttt{(m)} & socket.\\
    \hline    
  \end{tabular}
  \caption{Macro per i tipi di file (definite in \headfile{sys/stat.h}).}
  \label{tab:file_type_macro}
\end{table}

Queste macro vengono usate anche da Linux che supporta pure le estensioni allo
standard per i collegamenti simbolici e i socket definite da BSD.\footnote{le
  ultime due macro di tab.~\ref{tab:file_type_macro}, che non sono presenti
  nello standard POSIX fino alla revisione POSIX.1-1996.}  L'elenco completo
delle macro con cui è possibile estrarre da \var{st\_mode} l'informazione
relativa al tipo di file è riportato in tab.~\ref{tab:file_type_macro}, tutte
le macro restituiscono un valore intero da usare come valore logico e prendono
come argomento il valore di \var{st\_mode}.

\begin{table}[htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|c|l|}
    \hline
    \textbf{Flag} & \textbf{Valore} & \textbf{Significato} \\
    \hline
    \hline
    \const{S\_IFMT}   &  0170000 & Maschera per i bit del tipo di file.\\
    \const{S\_IFSOCK} &  0140000 & Socket.\\
    \const{S\_IFLNK}  &  0120000 & Collegamento simbolico.\\
    \const{S\_IFREG}  &  0100000 & File regolare.\\ 
    \const{S\_IFBLK}  &  0060000 & Dispositivo a blocchi.\\
    \const{S\_IFDIR}  &  0040000 & Directory.\\
    \const{S\_IFCHR}  &  0020000 & Dispositivo a caratteri.\\
    \const{S\_IFIFO}  &  0010000 & Fifo.\\
    \hline
    \const{S\_ISUID}  &  0004000 & \itindex{suid~bit} \acr{suid} bit.\\
    \const{S\_ISGID}  &  0002000 & \itindex{sgid~bit} \acr{sgid} bit.\\
    \const{S\_ISVTX}  &  0001000 & \itindex{sticky~bit} \acr{sticky} bit.\\
    \hline
    \const{S\_IRWXU}  &  00700   & Maschera per i permessi del proprietario.\\
    \const{S\_IRUSR}  &  00400   & Il proprietario ha permesso di lettura.\\
    \const{S\_IWUSR}  &  00200   & Il proprietario ha permesso di scrittura.\\
    \const{S\_IXUSR}  &  00100   & Il proprietario ha permesso di esecuzione.\\
    \hline
    \const{S\_IRWXG}  &  00070   & Maschera per i permessi del gruppo.\\
    \const{S\_IRGRP}  &  00040   & Il gruppo ha permesso di lettura.\\
    \const{S\_IWGRP}  &  00020   & Il gruppo ha permesso di scrittura.\\
    \const{S\_IXGRP}  &  00010   & Il gruppo ha permesso di esecuzione.\\
    \hline
    \const{S\_IRWXO}  &  00007   & Maschera per i permessi di tutti gli altri\\
    \const{S\_IROTH}  &  00004   & Gli altri hanno permesso di lettura.\\
    \const{S\_IWOTH}  &  00002   & Gli altri hanno permesso di esecuzione.\\
    \const{S\_IXOTH}  &  00001   & Gli altri hanno permesso di esecuzione.\\
    \hline    
  \end{tabular}
  \caption{Costanti per l'identificazione dei vari bit che compongono il campo
    \var{st\_mode} (definite in \headfile{sys/stat.h}).}
  \label{tab:file_mode_flags}
\end{table}

Oltre alle macro di tab.~\ref{tab:file_type_macro}, che semplificano
l'operazione, è possibile usare direttamente il valore di \var{st\_mode} per
ricavare il tipo di file controllando direttamente i vari bit in esso
memorizzati. Per questo sempre in \headfile{sys/stat.h} sono definite le varie
costanti numeriche riportate in tab.~\ref{tab:file_mode_flags}, che
definiscono le maschere che consentono di selezionare non solo i dati relativi
al tipo di file, ma anche le informazioni relative ai permessi su cui
torneremo in sez.~\ref{sec:file_access_control} ed identificare i rispettivi
valori.

Le costanti che servono per la identificazione del tipo di file sono riportate
nella prima sezione di tab.~\ref{tab:file_mode_flags}, mentre le sezioni
successive attengono alle costanti usate per i permessi.  Il primo valore
dell'elenco è la maschera binaria \const{S\_IFMT} che permette di estrarre da
\var{st\_mode} (con un AND aritmetico) il blocco di bit nei quali viene
memorizzato il tipo di file. I valori successivi sono le costanti
corrispondenti ai vari tipi di file, e possono essere usate per verificare la
presenza del tipo di file voluto ed anche, con opportune combinazioni,
alternative fra più tipi di file. 

Si tenga presente però che a differenza dei permessi, l'informazione relativa
al tipo di file non è una maschera binaria, per questo motivo se si volesse
impostare una condizione che permetta di controllare se un file è una
directory o un file ordinario non si possono controllare dei singoli bit, ma
si dovrebbe usare una macro di preprocessore come:
\includecodesnip{listati/is_regdir.h}
in cui si estraggono ogni volta da \var{st\_mode} i bit relativi al tipo di
file e poi si effettua il confronto con i due possibili tipi di file.


\subsection{Le dimensioni dei file}
\label{sec:file_file_size}

Abbiamo visto in fig.~\ref{fig:file_stat_struct} che campo \var{st\_size} di
una struttura \struct{stat} contiene la dimensione del file in byte. Questo
però è vero solo se si tratta di un file regolare, mentre nel caso di un
collegamento simbolico la dimensione è quella del \textit{pathname} che il
collegamento stesso contiene mentre per le fifo ed i file di dispositivo
questo campo è sempre nullo.

Il campo \var{st\_blocks} invece definisce la lunghezza del file in blocchi di
512 byte. La differenze con \var{st\_size} è che in questo caso si fa
riferimento alla quantità di spazio disco allocata per il file, e non alla
dimensione dello stesso che si otterrebbe leggendolo sequenzialmente.

Si deve tener presente infatti che la lunghezza del file riportata in
\var{st\_size} non è detto che corrisponda all'occupazione dello spazio su
disco, e non solo perché la parte finale del file potrebbe riempire
parzialmente un blocco. In un sistema unix-like infatti è possibile
l'esistenza dei cosiddetti \itindex{sparse~file} \textit{sparse file}, cioè
file in cui sono presenti dei ``\textsl{buchi}'' \index{file!\textit{hole}}
(\textit{holes} nella nomenclatura inglese) che si formano tutte le volte che
si va a scrivere su un file dopo aver eseguito uno spostamento oltre la sua
fine (tratteremo in dettaglio l'argomento in sez.~\ref{sec:file_lseek}).

In questo caso si avranno risultati differenti a seconda del modo in cui si
calcola la lunghezza del file, ad esempio il comando \cmd{du}, (che riporta il
numero di blocchi occupati) potrà dare una dimensione inferiore, mentre se si
legge dal file (ad esempio usando il comando \cmd{wc -c}), dato che in tal
caso per i ``\textsl{buchi}'' \index{file!\textit{hole}} vengono restituiti
degli zeri, si avrà lo stesso risultato di \cmd{ls}.

Se è sempre possibile allargare un file, scrivendoci sopra o usando la
funzione \func{lseek} (vedi sez.~\ref{sec:file_lseek}) per spostarsi oltre la
sua fine, esistono anche casi in cui si può avere bisogno di effettuare un
troncamento, scartando i dati presenti al di là della dimensione scelta come
nuova fine del file.

Un file può sempre essere troncato a zero aprendolo con il flag
\const{O\_TRUNC}, ma questo è un caso particolare; per qualunque altra
dimensione si possono usare le due funzioni di sistema \funcd{truncate} e
\funcd{ftruncate}, i cui prototipi sono:

\begin{funcproto}{
\fhead{unistd.h}
\fdecl{int ftruncate(int fd, off\_t length))}
\fdecl{int truncate(const char *file\_name, off\_t length)}
\fdesc{Troncano un file.} 
}
{Le funzioni ritornano $0$ in caso di successo e $-1$ per un errore, nel qual
  caso \var{errno} assumerà uno dei valori: 
  \begin{errlist}
  \item[\errcode{EINTR}] si è stati interrotti da un segnale.
  \item[\errcode{EINVAL}] \param{length} è negativa o maggiore delle
    dimensioni massime di un file.
  \item[\errcode{EPERM}] il filesystem non supporta il troncamento di un file.
  \item[\errcode{ETXTBSY}] il file è un programma in esecuzione.
  \end{errlist} 
  per entrambe, mentre per \func{ftruncate} si avranno anche: 
  \begin{errlist}
  \item[\errcode{EBADF}] \param{fd} non è un file descriptor.
  \item[\errcode{EINVAL}] \param{fd} non è un riferimento a un file o non è
    aperto in scrittura. 
  \end{errlist}
  e per \func{truncate} si avranno anche: 
  \begin{errlist}
  \item[\errcode{EACCES}] non si ha il permesso di scrittura sul file o il
    permesso di attraversamento di una delle componenti del \textit{pathname}.
  \item[\errcode{EISDIR}] \param{file\_name} fa riferimento ad una directory.
  \end{errlist}
  ed inoltre \errval{EFAULT}, \errval{EIO}, \errval{ELOOP},
  \errval{ENAMETOOLONG}, \errval{ENOENT}, \errval{ENOTDIR} e \errval{EROFS}
  nel loro significato generico.}
\end{funcproto}

Entrambe le funzioni fan sì che la dimensione del file sia troncata ad un
valore massimo specificato da \param{length}, e si distinguono solo per il
fatto che il file viene indicato con un \textit{pathname} per \func{truncate}
e con un file descriptor per \funcd{ftruncate}. Si tenga presente che se il
file è più lungo della lunghezza specificata i dati in eccesso saranno
perduti.

Il comportamento in caso di lunghezza del file inferiore a \param{length} non
è specificato e dipende dall'implementazione: il file può essere lasciato
invariato o esteso fino alla lunghezza scelta. Nel caso di Linux viene esteso
con la creazione di un \index{file!\textit{hole}} \textsl{buco} nel
\itindex{sparse~file} file e ad una lettura si otterranno degli zeri, si tenga
presente però che questo comportamento è supportato solo per filesystem
nativi, ad esempio su un filesystem non nativo come il VFAT di Windows questo
non è possibile.


\subsection{I tempi dei file}
\label{sec:file_file_times}

Il sistema mantiene per ciascun file tre tempi, che sono registrati
\itindex{inode} nell'\textit{inode} insieme agli altri attributi del
file. Questi possono essere letti tramite la funzione \func{stat}, che li
restituisce attraverso tre campi della struttura \struct{stat} di
fig.~\ref{fig:file_stat_struct}. Il significato di questi tempi e dei relativi
campi della struttura \struct{stat} è illustrato nello schema di
tab.~\ref{tab:file_file_times}, dove è anche riportato un esempio delle
funzioni che effettuano cambiamenti su di essi. Il valore del tempo è espresso
nel cosiddetto \itindex{calendar~time} \textit{calendar time}, su cui
torneremo in dettaglio in sez.~\ref{sec:sys_time}.

\begin{table}[htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|c|l|l|c|}
    \hline
    \textbf{Membro} & \textbf{Significato} & \textbf{Funzione} 
    & \textbf{Opzione di \cmd{ls}} \\
    \hline
    \hline
    \var{st\_atime}& ultimo accesso ai dati del file    &
                     \func{read}, \func{utime}          & \cmd{-u}\\
    \var{st\_mtime}& ultima modifica ai dati del file   &
                     \func{write}, \func{utime}         & default\\
    \var{st\_ctime}& ultima modifica ai dati dell'\textit{inode} &
                     \func{chmod}, \func{utime}         & \cmd{-c}\\
    \hline
  \end{tabular}
  \caption{I tre tempi associati a ciascun file.}
  \label{tab:file_file_times}
\end{table}

Il primo punto da tenere presente è la differenza fra il cosiddetto tempo di
ultima modifica (il \textit{modification time}) riportato in \var{st\_mtime},
ed il tempo di ultimo cambiamento di stato (il \textit{change status time})
riportato in \var{st\_ctime}. Il primo infatti fa riferimento ad una modifica
del contenuto di un file, mentre il secondo ad una modifica dei metadati
\itindex{inode} dell'\textit{inode}. Dato che esistono molte operazioni, come
la funzione \func{link} e altre che vedremo in seguito, che modificano solo le
informazioni contenute \itindex{inode} nell'\textit{inode} senza toccare il
contenuto del file, diventa necessario l'utilizzo di questo secondo tempo.

Il tempo di ultima modifica viene usato ad esempio da programmi come
\cmd{make} per decidere quali file necessitano di essere ricompilati perché
più recenti dei loro sorgenti oppure dai programmi di backup, talvolta insieme
anche al tempo di cambiamento di stato, per decidere quali file devono essere
aggiornati nell'archiviazione.  Il tempo di ultimo accesso viene di solito
usato per identificare i file che non vengono più utilizzati per un certo
lasso di tempo. Ad esempio un programma come \texttt{leafnode} lo usa per
cancellare gli articoli letti più vecchi, mentre \texttt{mutt} lo usa per
marcare i messaggi di posta che risultano letti.  

Il sistema non tiene mai conto dell'ultimo accesso \itindex{inode}
all'\textit{inode}, pertanto funzioni come \func{access} o \func{stat} non
hanno alcuna influenza sui tre tempi. Il comando \cmd{ls} (quando usato con le
opzioni \cmd{-l} o \cmd{-t}) mostra i tempi dei file secondo lo schema
riportato nell'ultima colonna di tab.~\ref{tab:file_file_times}. Si noti anche
come non esista, a differenza di altri sistemi operativi, un \textsl{tempo di
  creazione} di un file.

L'aggiornamento del tempo di ultimo accesso è stato a lungo considerato un
difetto progettuale di Unix, questo infatti comporta la necessità di
effettuare un accesso in scrittura sul disco anche in tutti i casi in cui
questa informazione non interessa e sarebbe possibile avere un semplice
accesso in lettura sui dati bufferizzati. Questo comporta un ovvio costo sia
in termini di prestazioni, che di consumo di risorse come la batteria per i
portatili, o i cicli di riscrittura per i dischi su memorie riscrivibili.


Per questo motivo abbiamo visto in sez.~\ref{sec:filesystem_mounting} come
nello sviluppo del kernel siano stati introdotti degli opportuni \textit{mount
  flag} che consentissero di evitare di aggiornare continuamente una
informazione che nella maggior parte dei casi non interessa. Per questo i
valori che si possono trovare per l'\textit{access time} dipendono dalle
opzioni di montaggio, ed anche, essendo stato cambiato il comportamento di
default a partire dalla versione 2.6.30, dal kernel che si sta usando. 

In generale quello che si ha con i kernel più recenti è che il tempo di ultimo
accesso viene aggiornato solo se è precedente al tempo di ultima modifica o
cambiamento, o se è passato più di un giorno dall'ultimo accesso. Così si può
rendere evidente che vi è stato un accesso dopo una modifica e che il file
viene comunque osservato regolarmente, conservando tutte le informazioni
veramente utili senza dover consumare risorse in scritture continue per
mantenere costantemente aggiornata una informazione che questo punto non ha
più nessuna rilevanza pratica.\footnote{qualora ce ne fosse la necessità è
  comunque possibile, tramite l'opzione di montaggio \texttt{strictatime},
  richiedere in ogni caso il comportamento tradizionale.}

\begin{table}[htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|c|c|c|c|c|c|l|}
    \hline
    \multicolumn{1}{|p{2.8cm}|}{\centering{\vspace{6pt}\textbf{Funzione}}} &
    \multicolumn{3}{|p{3.2cm}|}{\centering{
        \textbf{File o directory del riferimento}}}&
    \multicolumn{3}{|p{3.2cm}|}{\centering{
        \textbf{Directory contenente il riferimento}}} 
    &\multicolumn{1}{|p{3.4cm}|}{\centering{\vspace{6pt}\textbf{Note}}} \\
    \cline{2-7}
    \cline{2-7}
    \multicolumn{1}{|p{2.8cm}|}{} 
    &\multicolumn{1}{|p{.8cm}|}{\centering{\textsl{(a)}}}
    &\multicolumn{1}{|p{.8cm}|}{\centering{\textsl{(m)}}}
    &\multicolumn{1}{|p{.8cm}|}{\centering{\textsl{(c)}}}
    &\multicolumn{1}{|p{.8cm}|}{\centering{\textsl{(a)}}}
    &\multicolumn{1}{|p{.8cm}|}{\centering{\textsl{(m)}}}
    &\multicolumn{1}{|p{.8cm}|}{\centering{\textsl{(c)}}}
    &\multicolumn{1}{|p{3cm}|}{} \\
    \hline
    \hline
    \func{chmod}, \func{fchmod} 
             & --      & --      &$\bullet$& --      & --      & --      &\\
    \func{chown}, \func{fchown} 
             & --      & --      &$\bullet$& --      & --      & --      &\\
    \func{creat}  
             &$\bullet$&$\bullet$&$\bullet$& --      &$\bullet$&$\bullet$&  
             con \const{O\_CREATE} \\
    \func{creat}  
             & --      &$\bullet$&$\bullet$& --      &$\bullet$&$\bullet$&   
             con \const{O\_TRUNC} \\
    \func{exec}  
             &$\bullet$& --      & --      & --      & --      & --      &\\
    \func{lchown}  
             & --      & --      &$\bullet$& --      & --      & --      &\\
    \func{link}
             & --      & --      &$\bullet$& --      &$\bullet$&$\bullet$&\\
    \func{mkdir}
             &$\bullet$&$\bullet$&$\bullet$& --      &$\bullet$&$\bullet$&\\
    \func{mknod}
             &$\bullet$&$\bullet$&$\bullet$& --      &$\bullet$&$\bullet$&\\
    \func{mkfifo}
             &$\bullet$&$\bullet$&$\bullet$& --      &$\bullet$&$\bullet$&\\
    \func{open}
             &$\bullet$&$\bullet$&$\bullet$& --      &$\bullet$&$\bullet$& 
             con \const{O\_CREATE} \\
    \func{open}
             & --      &$\bullet$&$\bullet$& --      & --      & --      & 
             con \const{O\_TRUNC}  \\
    \func{pipe}
             &$\bullet$&$\bullet$&$\bullet$& --      & --      & --      &\\
    \func{read}
             &$\bullet$& --      & --      & --      & --      & --      &\\
    \func{remove}
             & --      & --      &$\bullet$& --      &$\bullet$&$\bullet$& 
             se esegue \func{unlink}\\
    \func{remove}
              & --      & --      & --      & --      &$\bullet$&$\bullet$& 
              se esegue \func{rmdir}\\
    \func{rename}
              & --      & --      &$\bullet$& --      &$\bullet$&$\bullet$& 
              per entrambi gli argomenti\\
    \func{rmdir}
              & --      & --      & --      & --      &$\bullet$&$\bullet$&\\ 
    \func{truncate}, \func{ftruncate}
              & --      &$\bullet$&$\bullet$& --      & --      & --      &\\ 
    \func{unlink}
              & --      & --      &$\bullet$& --      &$\bullet$&$\bullet$&\\ 
    \func{utime}
              &$\bullet$&$\bullet$&$\bullet$& --      & --      & --      &\\ 
    \func{utimes}
              &$\bullet$&$\bullet$&$\bullet$& --      & --      & --      &\\ 
    \func{write}
              & --      &$\bullet$&$\bullet$& --      & --      & --      &\\ 
    \hline
  \end{tabular}
  \caption{Prospetto dei cambiamenti effettuati sui tempi di ultimo 
    accesso \textsl{(a)}, ultima modifica \textsl{(m)} e ultimo cambiamento di
    stato \textsl{(c)} dalle varie funzioni operanti su file e directory.}
  \label{tab:file_times_effects}  
\end{table}


L'effetto delle varie funzioni di manipolazione dei file sui relativi tempi è
illustrato in tab.~\ref{tab:file_times_effects}, facendo riferimento al
comportamento classico per quanto riguarda \var{st\_atime}. Si sono riportati
gli effetti sia per il file a cui si fa riferimento, sia per la directory che
lo contiene. Questi ultimi possono essere capiti immediatamente se si tiene
conto di quanto già detto e ripetuto a partire da
sez.~\ref{sec:file_filesystem}, e cioè che anche le directory sono anch'esse
file che contengono una lista di nomi, che il sistema tratta in maniera del
tutto analoga a tutti gli altri.

Per questo motivo tutte le volte che compiremo un'operazione su un file che
comporta una modifica del nome contenuto nella directory, andremo anche a
scrivere sulla directory che lo contiene cambiandone il tempo di ultima
modifica. Un esempio di questo tipo di operazione può essere la cancellazione
di un file, invece leggere o scrivere o cambiare i permessi di un file ha
effetti solo sui tempi di quest'ultimo.

Si ricordi infine come \var{st\_ctime} non è il tempo di creazione del file,
che in Unix non esiste, anche se può corrispondervi per file che non sono mai
stati modificati. Per questo motivo, a differenza di quanto avviene con altri
sistemi operativi, quando si copia un file, a meno di preservare
esplicitamente i tempi (ad esempio con l'opzione \cmd{-p} di \cmd{cp}) esso
avrà sempre il tempo corrente in cui si è effettuata la copia come data di
ultima modifica.

I tempi di ultimo accesso ed ultima modifica possono essere modificati
esplicitamente usando la funzione di sistema \funcd{utime}, il cui prototipo
è:

\begin{funcproto}{
\fhead{utime.h}
\fdecl{int utime(const char *filename, struct utimbuf *times)}
\fdesc{Modifica i tempi di ultimo accesso ed ultima modifica di 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{EACCES}] non c'è il permesso di attraversamento per uno dei
    componenti di \param{filename} o \param{times} è \val{NULL} e non si ha il
    permesso di scrittura sul file, o non si è proprietari del file o non si
    hanno i privilegi di amministratore.
  \item[\errcode{EPERM}] \param{times} non è \val{NULL}, e non si è
    proprietari del file o non si hanno i privilegi di amministratore.
  \end{errlist}
  ed inoltre \errval{ENOENT} e \errval{EROFS} nel loro significato generico.}
\end{funcproto}

La funzione cambia i tempi di ultimo accesso e di ultima modifica del file
specificato dall'argomento \param{filename}, e richiede come secondo argomento
il puntatore ad una struttura \struct{utimbuf}, la cui definizione è riportata
in fig.~\ref{fig:struct_utimebuf}, con i nuovi valori di detti tempi
(rispettivamente nei campi \var{actime} e \var{modtime}). Se si passa un
puntatore nullo verrà impostato il tempo corrente.

\begin{figure}[!htb]
  \footnotesize \centering
  \begin{minipage}[c]{\textwidth}
    \includestruct{listati/utimbuf.h}
  \end{minipage} 
  \normalsize 
  \caption{La struttura \structd{utimbuf}, usata da \func{utime} per modificare
    i tempi dei file.}
  \label{fig:struct_utimebuf}
\end{figure}

L'effetto della funzione ed i privilegi necessari per eseguirla dipendono dal
valore dell'argomento \param{times}. Se è \val{NULL} la funzione imposta il
tempo corrente ed è sufficiente avere accesso in scrittura al file o essere
proprietari del file o avere i privilegi di amministratore. Se invece si è
specificato un valore diverso la funzione avrà successo solo se si è
proprietari del file o se si hanno i privilegi di amministratore.\footnote{per
  essere precisi la \itindex{capabilities} capacità \const{CAP\_FOWNER}.} In
entrambi i casi per verificare la proprietà del file viene utilizzato
l'\ids{UID} effettivo del processo.

Si tenga presente che non è possibile modificare manualmente il tempo di
cambiamento di stato del file, che viene aggiornato direttamente dal kernel
tutte le volte che si modifica \itindex{inode} l'\textit{inode}, e quindi
anche alla chiamata di \func{utime}.  Questo serve anche come misura di
sicurezza per evitare che si possa modificare un file nascondendo
completamente le proprie tracce. In realtà la cosa resta possibile se si è in
grado di accedere al \index{file!di~dispositivo} file di dispositivo,
scrivendo direttamente sul disco senza passare attraverso il filesystem, ma
ovviamente in questo modo la cosa è più complicata da
realizzare.\footnote{esistono comunque molti programmi che consentono di farlo
  con relativa semplicità per cui non si dia per scontato che il valore sia
  credibile in caso di macchina compromessa.}

A partire dal kernel 2.6 la risoluzione dei tempi dei file, che nei campi di
tab.~\ref{tab:file_file_times} è espressa in secondi, è stata portata ai
nanosecondi per la gran parte dei filesystem. La ulteriore informazione può
essere acceduta attraverso altri campi appositamente aggiunti alla struttura
\struct{stat}. Se si sono definite le macro \macro{\_BSD\_SOURCE} o
\macro{\_SVID\_SOURCE} questi sono \var{st\_atim.tv\_nsec},
\var{st\_mtim.tv\_nsec} e \var{st\_ctim.tv\_nsec} se queste non sono definite,
\var{st\_atimensec}, \var{st\_mtimensec} e \var{st\_mtimensec}. Qualora il
supporto per questa maggior precisione sia assente questi campi aggiuntivi
saranno nulli.

Per la gestione di questi nuovi valori è stata definita una seconda funzione
di sistema, \funcd{utimes}, che consente di specificare tempi con maggior
precisione; il suo prototipo è:

\begin{funcproto}{
\fhead{sys/time.h}
\fdecl{int utimes(const char *filename, struct timeval times[2])}
\fdesc{Modifica i tempi di ultimo accesso e ultima modifica di un file.} 
}
{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
  caso \var{errno} assumerà gli stessi valori di \func{utime}.}  
\end{funcproto}
 
La funzione è del tutto analoga alla precedente \func{utime} ma usa come
secondo argomento un vettore di due strutture \struct{timeval}, la cui
definizione è riportata in fig.~\ref{fig:sys_timeval_struct}, che consentono
di indicare i tempi con una precisione del microsecondo. Il primo elemento
di \param{times} indica il valore per il tempo di ultimo accesso, il secondo
quello per il tempo di ultima modifica. Se si indica come secondo argomento un
puntatore nullo di nuovo verrà utilizzato il tempo corrente.

\begin{figure}[!htb]
  \footnotesize \centering
  \begin{minipage}[c]{\textwidth}
    \includestruct{listati/timeval.h}
  \end{minipage} 
  \normalsize 
  \caption{La struttura \structd{timeval} usata per indicare valori di tempo
    con la precisione del microsecondo.}
  \label{fig:sys_timeval_struct}
\end{figure}

Oltre ad \func{utimes} su Linux sono presenti altre due funzioni,\footnote{le
  due funzioni non sono definite in nessuno standard, ma sono presenti, oltre
  che su Linux, anche su BSD.} \funcd{futimes} e \funcd{lutimes}, che
consentono rispettivamente di effettuare la modifica utilizzando un file già
aperto o di eseguirla direttamente su un collegamento simbolico. I relativi
prototipi sono:

\begin{funcproto}{
\fhead{sys/time.h}
\fdecl{int futimes(int fd, const struct timeval tv[2])}
\fdesc{Cambia i tempi di un file già aperto.} 
\fdecl{int lutimes(const char *filename, const struct timeval tv[2])}
\fdesc{Cambia i tempi di un collegamento simbolico.} 
}

{Le funzioni ritornano $0$ in caso di successo e $-1$ per un errore, nel qual
  caso \var{errno} assumerà uno gli stessi valori di \func{utimes}, con in più
  per \func{futimes}:
  \begin{errlist}
  \item[\errcode{EBADF}] \param{fd} non è un file descriptor.
  \item[\errcode{ENOSYS}] il filesystem \texttt{/proc} non è accessibile.
  \end{errlist}}  
\end{funcproto}

Le due funzioni anno lo stesso comportamento di \texttt{utimes} e richiedono
gli stessi privilegi per poter operare, la differenza è che con \func{futimes}
si può indicare il file su cui operare se questo è già aperto facendo
riferimento al suo file descriptor mentre con \func{lutimes} nel caso in
cui \param{filename} sia un collegamento simbolico saranno modificati i suoi
tempi invece di quelli del file a cui esso punta.

Nonostante il kernel, come accennato, supporti risoluzioni dei tempi dei file
fino al nanosecondo, le funzioni fin qui esaminate non consentono di impostare
valori con questa precisione. Per questo sono state introdotte due nuove
funzioni, \funcd{futimens} e \func{utimensat}, in grado di eseguire questo
compito; i rispettivi prototipi sono:

\begin{funcproto}{
\fhead{sys/time.h}
\fdecl{futimens(int fd, const struct timespec times[2])}
\fdesc{Cambia i tempi di un file già aperto.} 
\fdecl{int utimensat(int dirfd, const char *pathname, const struct
    timespec times[2], int flags)}
\fdesc{Cambia i tempi di un file.} 
}
{Le funzioni ritornano $0$ in caso di successo e $-1$ per un errore, nel qual
  caso \var{errno} assumerà uno dei valori: 
  \begin{errlist}
  \item[\errcode{EBADF}] da fare
  \end{errlist}
  ed inoltre nel loro significato generico.}
\end{funcproto}

Entrambe le funzioni utilizzano per indicare i valori dei tempi un
vettore \param{times} di due strutture \struct{timespec} che permette di
specificare un valore di tempo con una precisione fino al nanosecondo, la cui
definizione è riportata in fig.~\ref{fig:sys_timespec_struct}.

\begin{figure}[!htb]
  \footnotesize \centering
  \begin{minipage}[c]{\textwidth}
    \includestruct{listati/timespec.h}
  \end{minipage} 
  \normalsize 
  \caption{La struttura \structd{timespec} usata per indicare valori di tempo
    con la precisione del nanosecondo.}
  \label{fig:sys_timespec_struct}
\end{figure}

Come per le precedenti funzioni il primo elemento di \param{times} indica il
tempo di ultimo accesso ed il secondo quello di ultima modifica, e se si usa
il valore \val{NULL} verrà impostato il tempo corrente sia per l'ultimo
accesso che per l'ultima modifica. Nei singoli elementi di \param{times} si
possono inoltre utilizzare due valori speciali per il campo \var{tv\_nsec}:
con \const{UTIME\_NOW} si richiede l'uso del tempo corrente, mentre con
\const{UTIME\_OMIT} si richiede di non impostare il tempo. Si può così
aggiornare in maniera specifica soltanto uno fra il tempo di ultimo accesso e
quello di ultima modifica. Quando si usa uno di questi valori speciali per
\var{tv\_nsec} il corrispondente valore di \var{tv\_sec} viene ignorato.

Queste due funzioni sono una estensione definita nella revisione POSIX.1-2008
dello standard POSIX; sono state introdotte a partire dal 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}, è stata
  dichiarata obsoleta, non è supportata da nessuno standard e non deve essere
  più utilizzata: pertanto non la tratteremo.} La prima è sostanzialmente una
estensione di \func{futimes} che consente di specificare i tempi con
precisione maggiore, la seconda supporta invece, rispetto ad \func{utimes},
una sintassi più complessa che, come vedremo in sez.~\ref{sec:file_openat}
consente una indicazione sicura dei \itindsub{pathname}{relativo}
\textit{pathname relativi} specificando la directory da usare come riferimento
in \param{dirfd} e la possibilità di usare per \param{flags} il valore
\const{AT\_SYMLINK\_NOFOLLOW} per indicare alla funzione di non dereferenziare
i collegamenti simbolici; si rimanda pertanto la spiegazione del significato
degli argomenti aggiuntivi alla trattazione generica delle varie funzioni che
usano la stessa sintassi, effettuata in sez.~\ref{sec:file_openat}.


\section{Il controllo di accesso ai file}
\label{sec:file_access_control}

Una delle caratteristiche fondamentali di tutti i sistemi unix-like è quella
del controllo di accesso ai file, che viene implementato per qualunque
filesystem standard.\footnote{per standard si intende che implementa le
  caratteristiche previste dallo standard POSIX; in Linux sono disponibili
  anche una serie di altri filesystem, come quelli di Windows e del Mac, che
  non supportano queste caratteristiche.} In questa sezione ne esamineremo i
concetti essenziali e le funzioni usate per gestirne i vari aspetti.


\subsection{I permessi per l'accesso ai file}
\label{sec:file_perm_overview}

Ad ogni file Linux associa sempre l'utente che ne è proprietario (il
cosiddetto \textit{owner}) ed un gruppo di appartenenza, secondo il meccanismo
degli identificatori di utente e gruppo (\ids{UID} e \ids{GID}). Questi valori
sono accessibili da programma tramite la funzione \func{stat}, e sono
mantenuti nei campi \var{st\_uid} e \var{st\_gid} della struttura
\struct{stat} (si veda sez.~\ref{sec:file_stat}).\footnote{questo è vero solo
  per filesystem di tipo Unix, ad esempio non è vero per il filesystem vfat di
  Windows, che non fornisce nessun supporto per l'accesso multiutente, e per
  il quale i permessi vengono assegnati in maniera fissa con un opzione in
  fase di montaggio.}

Il controllo di accesso ai file segue un modello abbastanza semplice che
prevede tre permessi fondamentali strutturati su tre livelli di accesso.
Esistono varie estensioni a questo modello,\footnote{come le
  \itindex{Access~Control~List~(ACL)} \textit{Access Control List} che sono
  state aggiunte ai filesystem standard con opportune estensioni (vedi
  sez.~\ref{sec:file_ACL}) per arrivare a meccanismi di controllo ancora più
  sofisticati come il \textit{mandatory access control} di SE-Linux.} ma nella
maggior parte dei casi il meccanismo standard è più che sufficiente a
soddisfare tutte le necessità più comuni.  I tre permessi di base associati ad
ogni file sono:
\begin{itemize*}
\item il permesso di lettura (indicato con la lettera \texttt{r}, dall'inglese
  \textit{read}).
\item il permesso di scrittura (indicato con la lettera \texttt{w},
  dall'inglese \textit{write}).
\item il permesso di esecuzione (indicato con la lettera \texttt{x},
  dall'inglese \textit{execute}).
\end{itemize*}
mentre i tre livelli su cui sono divisi i privilegi sono:
\begin{itemize*}
\item i privilegi per l'utente proprietario del file.
\item i privilegi per un qualunque utente faccia parte del gruppo cui
  appartiene il file.
\item i privilegi per tutti gli altri utenti.
\end{itemize*}

L'insieme dei permessi viene espresso con un numero a 12 bit; di questi i nove
meno significativi sono usati a gruppi di tre per indicare i permessi base di
lettura, scrittura ed esecuzione e sono applicati rispettivamente
rispettivamente al proprietario, al gruppo, a tutti gli altri.

\begin{figure}[htb]
  \centering
  \includegraphics[width=6cm]{img/fileperm}
  \caption{Lo schema dei bit utilizzati per specificare i permessi di un file
    contenuti nel campo \var{st\_mode} di \struct{stat}.}
  \label{fig:file_perm_bit}
\end{figure}

I restanti tre bit (noti come \itindex{suid~bit} \textit{suid bit},
\itindex{sgid~bit} \textit{sgid bit}, e \itindex{sticky~bit} \textit{sticky
  bit}) sono usati per indicare alcune caratteristiche più complesse del
meccanismo del controllo di accesso su cui torneremo in seguito (in
sez.~\ref{sec:file_special_perm}); lo schema di allocazione dei bit è
riportato in fig.~\ref{fig:file_perm_bit}.

Anche i permessi, come tutte le altre informazioni pertinenti al file, sono
memorizzati \itindex{inode} nell'\textit{inode}; in particolare essi sono
contenuti in alcuni bit del campo \var{st\_mode} della struttura \struct{stat}
(si veda di nuovo fig.~\ref{fig:file_stat_struct}).

In genere ci si riferisce ai tre livelli dei privilegi usando le lettere
\texttt{u} (per \textit{user}), \texttt{g} (per \textit{group}) e \texttt{o}
(per \textit{other}), inoltre se si vuole indicare tutti i raggruppamenti
insieme si usa la lettera \texttt{a} (per \textit{all}). Si tenga ben presente
questa distinzione dato che in certi casi, mutuando la terminologia in uso nel
VMS, si parla dei permessi base come di permessi per \textit{owner},
\textit{group} ed \textit{all}, le cui iniziali possono dar luogo a
confusione.  Le costanti che permettono di accedere al valore numerico di
questi bit nel campo \var{st\_mode} sono riportate in
tab.~\ref{tab:file_bit_perm}.

\begin{table}[htb]
  \centering
    \footnotesize
  \begin{tabular}[c]{|c|l|}
    \hline
    \textbf{\var{st\_mode}} bit & \textbf{Significato} \\
    \hline 
    \hline 
    \const{S\_IRUSR} & \textit{user-read}, l'utente può leggere.\\
    \const{S\_IWUSR} & \textit{user-write}, l'utente può scrivere.\\
    \const{S\_IXUSR} & \textit{user-execute}, l'utente può eseguire.\\ 
    \hline            
    \const{S\_IRGRP} & \textit{group-read}, il gruppo può leggere.\\
    \const{S\_IWGRP} & \textit{group-write}, il gruppo può scrivere.\\
    \const{S\_IXGRP} & \textit{group-execute}, il gruppo può eseguire.\\
    \hline            
    \const{S\_IROTH} & \textit{other-read}, tutti possono leggere.\\
    \const{S\_IWOTH} & \textit{other-write}, tutti possono scrivere.\\
    \const{S\_IXOTH} & \textit{other-execute}, tutti possono eseguire.\\
    \hline              
  \end{tabular}
  \caption{I bit dei permessi di accesso ai file, come definiti in 
    \texttt{<sys/stat.h>}}
  \label{tab:file_bit_perm}
\end{table}

I permessi vengono usati in maniera diversa dalle varie funzioni, e a seconda
che si riferiscano a dei file, dei collegamenti simbolici o delle directory;
qui ci limiteremo ad un riassunto delle regole generali, entrando nei dettagli
più avanti.

La prima regola è che per poter accedere ad un file attraverso il suo
\textit{pathname} occorre il permesso di esecuzione in ciascuna delle
directory che compongono il \textit{pathname}; lo stesso vale per aprire un
file nella directory corrente (per la quale appunto serve il diritto di
esecuzione).

Per una directory infatti il permesso di esecuzione significa che essa può
essere attraversata nella risoluzione del \textit{pathname}, ed è distinto dal
permesso di lettura che invece implica che si può leggere il contenuto della
directory.

Questo significa che se si ha il permesso di esecuzione senza permesso di
lettura si potrà lo stesso aprire un file in una directory (se si hanno i
permessi opportuni per il medesimo) ma non si potrà vederlo con \cmd{ls}
(mentre per crearlo occorrerà anche il permesso di scrittura per la
directory).

Avere il permesso di lettura per un file consente di aprirlo con le opzioni
(si veda quanto riportato in tab.~\ref{tab:file_open_flags}) di sola lettura o
di lettura/scrittura e leggerne il contenuto. Avere il permesso di scrittura
consente di aprire un file in sola scrittura o lettura/scrittura e modificarne
il contenuto, lo stesso permesso è necessario per poter troncare il file.

Non si può creare un file fintanto che non si disponga del permesso di
esecuzione e di quello di scrittura per la directory di destinazione; gli
stessi permessi occorrono per cancellare un file da una directory (si ricordi
che questo non implica necessariamente la rimozione del contenuto del file dal
disco), non è necessario nessun tipo di permesso per il file stesso (infatti
esso non viene toccato, viene solo modificato il contenuto della directory,
rimuovendo la voce che ad esso fa riferimento).

Per poter eseguire un file (che sia un programma compilato od uno script di
shell, od un altro tipo di file eseguibile riconosciuto dal kernel), occorre
avere il permesso di esecuzione, inoltre solo i file regolari possono essere
eseguiti.

I permessi per un collegamento simbolico sono ignorati, contano quelli del
file a cui fa riferimento; per questo in genere il comando \cmd{ls} riporta
per un collegamento simbolico tutti i permessi come concessi; utente e gruppo
a cui esso appartiene vengono pure ignorati quando il collegamento viene
risolto, vengono controllati solo quando viene richiesta la rimozione del
collegamento e quest'ultimo è in una directory con lo \itindex{sticky~bit}
\textit{sticky bit} impostato (si veda sez.~\ref{sec:file_special_perm}).

La procedura con cui il kernel stabilisce se un processo possiede un certo
permesso (di lettura, scrittura o esecuzione) si basa sul confronto fra
l'utente e il gruppo a cui il file appartiene (i valori di \var{st\_uid} e
\var{st\_gid} accennati in precedenza) e l'\ids{UID} effettivo, il \ids{GID}
effettivo e gli eventuali \ids{GID} supplementari del processo.\footnote{in
  realtà Linux, per quanto riguarda l'accesso ai file, utilizza gli
  identificatori del gruppo \textit{filesystem} (si ricordi quanto esposto in
  sez.~\ref{sec:proc_perms}), ma essendo questi del tutto equivalenti ai primi,
  eccetto il caso in cui si voglia scrivere un server NFS, ignoreremo questa
  differenza.}

Per una spiegazione dettagliata degli identificatori associati ai processi si
veda sez.~\ref{sec:proc_perms}; normalmente, a parte quanto vedremo in
sez.~\ref{sec:file_special_perm}, l'\ids{UID} effettivo e il \ids{GID} effettivo
corrispondono ai valori dell'\ids{UID} e del \ids{GID} dell'utente che ha
lanciato il processo, mentre i \ids{GID} supplementari sono quelli dei gruppi
cui l'utente appartiene.

I passi attraverso i quali viene stabilito se il processo possiede il diritto
di accesso sono i seguenti:
\begin{enumerate*}
\item Se l'\ids{UID} effettivo del processo è zero (corrispondente
  all'amministratore) l'accesso è sempre garantito senza nessun ulteriore
  controllo. Per questo motivo \textsl{root} ha piena libertà di accesso a
  tutti i file.
\item Se l'\ids{UID} effettivo del processo è uguale all'\ids{UID} del
  proprietario del file (nel qual caso si dice che il processo è proprietario
  del file) allora:
  \begin{itemize*}
  \item se il relativo\footnote{per relativo si intende il bit di user-read se
      il processo vuole accedere in lettura, quello di user-write per
      l'accesso in scrittura, ecc.} bit dei permessi d'accesso dell'utente è
    impostato, l'accesso è consentito
  \item altrimenti l'accesso è negato
  \end{itemize*}
\item Se il \ids{GID} effettivo del processo o uno dei \ids{GID} supplementari
  dei processi corrispondono al \ids{GID} del file allora:
  \begin{itemize*}
  \item se il bit dei permessi d'accesso del gruppo è impostato, l'accesso è
    consentito, 
  \item altrimenti l'accesso è negato
  \end{itemize*}
\item Se il bit dei permessi d'accesso per tutti gli altri è impostato,
  l'accesso è consentito, altrimenti l'accesso è negato.
\end{enumerate*}

Si tenga presente che questi passi vengono eseguiti esattamente in
quest'ordine. Questo vuol dire che se un processo è il proprietario di un file,
l'accesso è consentito o negato solo sulla base dei permessi per l'utente; i
permessi per il gruppo non vengono neanche controllati. Lo stesso vale se il
processo appartiene ad un gruppo appropriato, in questo caso i permessi per
tutti gli altri non vengono controllati.


\subsection{I bit dei permessi speciali}
\label{sec:file_special_perm}

\itindbeg{suid~bit}
\itindbeg{sgid~bit}

Come si è accennato (in sez.~\ref{sec:file_perm_overview}) nei dodici bit del
campo \var{st\_mode} di \struct{stat} che vengono usati per il controllo di
accesso oltre ai bit dei permessi veri e propri, ci sono altri tre bit che
vengono usati per indicare alcune proprietà speciali dei file.  Due di questi
sono i bit detti \acr{suid} (da \textit{set-user-ID bit}) e \acr{sgid} (da
\textit{set-group-ID bit}) che sono identificati dalle costanti
\const{S\_ISUID} e \const{S\_ISGID}.

Come spiegato in dettaglio in sez.~\ref{sec:proc_exec}, quando si lancia un
programma il comportamento normale del kernel è quello di impostare gli
identificatori del gruppo \textit{effective} del nuovo processo al valore dei
corrispondenti del gruppo \textit{real} del processo corrente, che normalmente
corrispondono a quelli dell'utente con cui si è entrati nel sistema.

Se però il file del programma (che ovviamente deve essere
eseguibile\footnote{per motivi di sicurezza il kernel ignora i bit \acr{suid}
  e \acr{sgid} per gli script eseguibili.}) ha il bit \acr{suid} impostato, il
kernel assegnerà come \ids{UID} effettivo al nuovo processo l'\ids{UID} del
proprietario del file al posto dell'\ids{UID} del processo originario.  Avere
il bit \acr{sgid} impostato ha lo stesso effetto sul \ids{GID} effettivo del
processo.

I bit \acr{suid} e \acr{sgid} vengono usati per permettere agli utenti normali
di usare programmi che richiedono privilegi speciali; l'esempio classico è il
comando \cmd{passwd} che ha la necessità di modificare il file delle password,
quest'ultimo ovviamente può essere scritto solo dall'amministratore, ma non è
necessario chiamare l'amministratore per cambiare la propria password. Infatti
il comando \cmd{passwd} appartiene a root ma ha il bit \acr{suid} impostato
per cui quando viene lanciato da un utente normale parte con i privilegi di
root.

Chiaramente avere un processo che ha privilegi superiori a quelli che avrebbe
normalmente l'utente che lo ha lanciato comporta vari rischi, e questo tipo di
programmi devono essere scritti accuratamente per evitare che possano essere
usati per guadagnare privilegi non consentiti (l'argomento è affrontato in
dettaglio in sez.~\ref{sec:proc_perms}).

La presenza dei bit \acr{suid} e \acr{sgid} su un file può essere rilevata con
il comando \cmd{ls -l}, che visualizza una lettera \cmd{s} al posto della
\cmd{x} in corrispondenza dei permessi di utente o gruppo. La stessa lettera
\cmd{s} può essere usata nel comando \cmd{chmod} per impostare questi bit.
Infine questi bit possono essere controllati all'interno di \var{st\_mode} con
l'uso delle due costanti \const{S\_ISUID} e \const{S\_IGID}, i cui valori sono
riportati in tab.~\ref{tab:file_mode_flags}.

Gli stessi bit vengono ad assumere in significato completamente diverso per le
directory, normalmente infatti Linux usa la convenzione di SVr4 per indicare
con questi bit l'uso della semantica BSD nella creazione di nuovi file (si
veda sez.~\ref{sec:file_ownership_management} per una spiegazione dettagliata
al proposito).

Infine Linux utilizza il bit \acr{sgid} per un'ulteriore estensione mutuata
da SVr4. Il caso in cui un file ha il bit \acr{sgid} impostato senza che lo
sia anche il corrispondente bit di esecuzione viene utilizzato per attivare
per quel file il \itindex{mandatory~locking} \textit{mandatory locking}
(affronteremo questo argomento in dettaglio più avanti, in
sez.~\ref{sec:file_mand_locking}).

\itindend{suid~bit}
\itindend{sgid~bit}


\itindbeg{sticky~bit}

L'ultimo dei bit rimanenti, identificato dalla costante \const{S\_ISVTX}, è in
parte un rimasuglio delle origini dei sistemi Unix. A quell'epoca infatti la
memoria virtuale e l'accesso ai file erano molto meno sofisticati e per
ottenere la massima velocità possibile per i programmi usati più comunemente
si poteva impostare questo bit.

L'effetto di questo bit era che il \index{segmento!testo} segmento di testo
del programma (si veda sez.~\ref{sec:proc_mem_layout} per i dettagli) veniva
scritto nella swap la prima volta che questo veniva lanciato, e vi permaneva
fino al riavvio della macchina (da questo il nome di \textsl{sticky bit});
essendo la swap un file continuo o una partizione indicizzata direttamente si
poteva risparmiare in tempo di caricamento rispetto alla ricerca attraverso la
struttura del filesystem. Lo \textsl{sticky bit} è indicato usando la lettera
\texttt{t} al posto della \texttt{x} nei permessi per gli altri.

Ovviamente per evitare che gli utenti potessero intasare la swap solo
l'amministratore era in grado di impostare questo bit, che venne chiamato
anche con il nome di \textit{saved text bit}, da cui deriva quello della
costante.  Le attuali implementazioni di memoria virtuale e filesystem rendono
sostanzialmente inutile questo procedimento.

Benché ormai non venga più utilizzato per i file, lo \textit{sticky bit} ha
invece assunto un uso importante per le directory;\footnote{lo \textit{sticky
    bit} per le directory è un'estensione non definita nello standard POSIX,
  Linux però la supporta, così come BSD e SVr4.} in questo caso se tale bit è
impostato un file potrà essere rimosso dalla directory soltanto se l'utente ha
il permesso di scrittura su di essa ed inoltre è vera una delle seguenti
condizioni:
\begin{itemize*}
\item l'utente è proprietario del file
\item l'utente è proprietario della directory
\item l'utente è l'amministratore 
\end{itemize*}
un classico esempio di directory che ha questo bit impostato è \file{/tmp}, i
permessi infatti di solito sono i seguenti:
\begin{verbatim}
$ ls -ld /tmp
drwxrwxrwt    6 root     root         1024 Aug 10 01:03 /tmp
\end{verbatim}%$
quindi con lo \textit{sticky bit} bit impostato. In questo modo qualunque
utente nel sistema può creare dei file in questa directory (che, come
suggerisce il nome, è normalmente utilizzata per la creazione di file
temporanei), ma solo l'utente che ha creato un certo file potrà cancellarlo o
rinominarlo. In questo modo si evita che un utente possa, più o meno
consapevolmente, cancellare i file temporanei creati degli altri utenti.

\itindend{sticky~bit}

\subsection{Le funzioni per la gestione dei permessi dei file}
\label{sec:file_perm_management}

Come visto in sez.~\ref{sec:file_access_control} il controllo di accesso ad un
file viene fatto utilizzando l'\ids{UID} ed il \ids{GID} effettivo del processo;
ci sono casi però in cui si può voler effettuare il controllo con l'\ids{UID}
reale ed il \ids{GID} reale, vale a dire usando i valori di \ids{UID} e
\ids{GID} relativi all'utente che ha lanciato il programma, e che, come
accennato in sez.~\ref{sec:file_special_perm} e spiegato in dettaglio in
sez.~\ref{sec:proc_perms}, non è detto siano uguali a quelli effettivi.

Per far questo si può usare la funzione \funcd{access}, il cui prototipo è:

\begin{funcproto}{
\fhead{unistd.h}
\fdecl{int access(const char *pathname, int mode)}
\fdesc{Verifica i permessi di accesso.} 
}

{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{EINVAL}] il valore di \param{mode} non è valido.
  \item[\errcode{EACCES}] l'accesso al file non è consentito, o non si ha il
    permesso di attraversare una delle directory di \param{pathname}.
  \item[\errcode{EROFS}] si è richiesto l'accesso in scrittura per un file su
    un filesystem montato in sola lettura.
  \end{errlist}
  ed inoltre \errval{EFAULT}, \errval{ENAMETOOLONG}, \errval{ENOENT},
  \errval{ENOTDIR}, \errval{ELOOP}, \errval{EIO}
 nel loro significato generico.}
\end{funcproto}

La funzione verifica i permessi di accesso, indicati da \param{mode}, per il
file indicato da \param{pathname}. I valori possibili per l'argomento
\param{mode} sono esprimibili come combinazione delle costanti numeriche
riportate in tab.~\ref{tab:file_access_mode_val} (attraverso un OR binario
delle stesse). I primi tre valori implicano anche la verifica dell'esistenza
del file, se si vuole verificare solo quest'ultima si può usare \const{F\_OK},
o anche direttamente \func{stat}. Nel caso in cui \param{pathname} si
riferisca ad un collegamento simbolico, questo viene seguito ed il controllo è
fatto sul file a cui esso fa riferimento.

La funzione controlla solo i bit dei permessi di accesso, si ricordi che il
fatto che una directory abbia permesso di scrittura non significa che ci si
possa scrivere come in un file, e il fatto che un file abbia permesso di
esecuzione non comporta che contenga un programma eseguibile. La funzione
ritorna zero solo se tutte i permessi controllati sono disponibili, in caso
contrario (o di errore) ritorna -1.
\begin{table}[htb]
  \centering
  \footnotesize
  \begin{tabular}{|c|l|}
    \hline
    \textbf{\param{mode}} & \textbf{Significato} \\
    \hline
    \hline
    \const{R\_OK} & Verifica il permesso di lettura. \\
    \const{W\_OK} & Verifica il permesso di scrittura. \\
    \const{X\_OK} & Verifica il permesso di esecuzione. \\
    \const{F\_OK} & Verifica l'esistenza del file. \\
    \hline
  \end{tabular}
  \caption{Valori possibile per l'argomento \param{mode} della funzione 
    \func{access}.}
  \label{tab:file_access_mode_val}
\end{table}

Un esempio tipico per l'uso di questa funzione è quello di un processo che sta
eseguendo un programma coi privilegi di un altro utente (ad esempio attraverso
l'uso del \itindex{suid~bit} \textit{suid bit}) che vuole controllare se
l'utente originale ha i permessi per accedere ad un certo file.

Del tutto analoghe a \func{access} sono le due funzioni \funcd{euidaccess} e
\funcd{eaccess} che ripetono lo stesso controllo usando però gli
identificatori del gruppo effettivo, verificando quindi le effettive capacità
di accesso ad un file. Le funzioni hanno entrambe lo stesso
prototipo\footnote{in realtà \func{eaccess} è solo un sinonimo di
  \func{euidaccess} fornita per compatibilità con l'uso di questo nome in
  altri sistemi.} che è del tutto identico a quello di \func{access}. Prendono
anche gli stessi valori e restituiscono gli stessi risultati e gli stessi
codici di errore.

Per cambiare i permessi di un file il sistema mette ad disposizione due
funzioni \funcd{chmod} e \funcd{fchmod}, che operano rispettivamente su un
filename e su un file descriptor, i loro prototipi sono:

\begin{funcproto}{
\fhead{sys/types.h}
\fhead{sys/stat.h}
\fdecl{int chmod(const char *path, mode\_t mode)}
\fdesc{Cambia i permessi del file indicato da \param{path} al valore indicato
  da \param{mode}.} 
\fdecl{int fchmod(int fd, mode\_t mode)}
\fdesc{Analoga alla precedente, ma usa il file descriptor \param{fd} per
  indicare il 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{EPERM}] l'\ids{UID} effettivo non corrisponde a quello del
    proprietario del file o non è zero.
  \item[\errcode{EROFS}] il file è su un filesystem in sola lettura.
  \end{errlist}
  ed inoltre per entrambe \errval{EIO}, per  \func{chmod} \errval{EFAULT},
  \errval{ENAMETOOLONG}, \errval{ENOENT}, \errval{ENOMEM}, \errval{ENOTDIR},
  \errval{EACCES}, \errval{ELOOP}, per \func{fchmod} \errval{EBADF}
 nel loro significato generico.}
\end{funcproto}


Entrambe le funzioni utilizzano come secondo argomento \param{mode}, una
variabile dell'apposito tipo primitivo \type{mode\_t} (vedi
tab.~\ref{tab:intro_primitive_types}) utilizzato per specificare i permessi sui
file.

\begin{table}[!htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|c|c|l|}
    \hline
    \textbf{\param{mode}} & \textbf{Valore} & \textbf{Significato} \\
    \hline
    \hline
    \const{S\_ISUID} & 04000 & Set user ID \itindex{suid~bit}.\\
    \const{S\_ISGID} & 02000 & Set group ID \itindex{sgid~bit}.\\
    \const{S\_ISVTX} & 01000 & Sticky bit \itindex{sticky~bit}.\\
    \hline
    \const{S\_IRWXU} & 00700 & L'utente ha tutti i permessi.\\
    \const{S\_IRUSR} & 00400 & L'utente ha il permesso di lettura.\\
    \const{S\_IWUSR} & 00200 & L'utente ha il permesso di scrittura.\\
    \const{S\_IXUSR} & 00100 & L'utente ha il permesso di esecuzione.\\
    \hline
    \const{S\_IRWXG} & 00070 & Il gruppo ha tutti i permessi.\\
    \const{S\_IRGRP} & 00040 & Il gruppo ha il permesso di lettura.\\
    \const{S\_IWGRP} & 00020 & Il gruppo ha il permesso di scrittura.\\
    \const{S\_IXGRP} & 00010 & Il gruppo ha il permesso di esecuzione.\\
    \hline
    \const{S\_IRWXO} & 00007 & Gli altri hanno tutti i permessi.\\
    \const{S\_IROTH} & 00004 & Gli altri hanno il permesso di lettura.\\
    \const{S\_IWOTH} & 00002 & Gli altri hanno il permesso di scrittura.\\
    \const{S\_IXOTH} & 00001 & Gli altri hanno il permesso di esecuzione.\\
    \hline
  \end{tabular}
  \caption{Valori delle costanti usate per indicare i vari bit di
    \param{mode} utilizzato per impostare i permessi dei file.}
  \label{tab:file_permission_const}
\end{table}

Le costanti con cui specificare i singoli bit di \param{mode} sono riportate
in tab.~\ref{tab:file_permission_const}. Il valore di \param{mode} può essere
ottenuto combinando fra loro con un OR binario le costanti simboliche relative
ai vari bit, o specificato direttamente, come per l'omonimo comando di shell,
con un valore numerico (la shell lo vuole in ottale, dato che i bit dei
permessi sono divisibili in gruppi di tre), che si può calcolare direttamente
usando lo schema si utilizzo dei bit illustrato in
fig.~\ref{fig:file_perm_bit}.

Ad esempio i permessi standard assegnati ai nuovi file (lettura e scrittura
per il proprietario, sola lettura per il gruppo e gli altri) sono
corrispondenti al valore ottale $0644$, un programma invece avrebbe anche il
bit di esecuzione attivo, con un valore di $0755$, se si volesse attivare il
bit \itindex{suid~bit} \acr{suid} il valore da fornire sarebbe $4755$.

Il cambiamento dei permessi di un file eseguito attraverso queste funzioni ha
comunque alcune limitazioni, previste per motivi di sicurezza. L'uso delle
funzioni infatti è possibile solo se l'\ids{UID} effettivo del processo
corrisponde a quello del proprietario del file o dell'amministratore,
altrimenti esse falliranno con un errore di \errcode{EPERM}.

Ma oltre a questa regola generale, di immediata comprensione, esistono delle
limitazioni ulteriori. Per questo motivo, anche se si è proprietari del file,
non tutti i valori possibili di \param{mode} sono permessi o hanno effetto;
in particolare accade che:
\begin{enumerate}
\item siccome solo l'amministratore può impostare lo \itindex{sticky~bit}
  \textit{sticky bit}, se l'\ids{UID} effettivo del processo non è zero esso
  viene automaticamente cancellato (senza notifica di errore) qualora sia
  stato indicato in \param{mode}.
\item per quanto detto in sez.~\ref{sec:file_ownership_management} riguardo la
  creazione dei nuovi file, si può avere il caso in cui il file creato da un
  processo è assegnato ad un gruppo per il quale il processo non ha privilegi.
  Per evitare che si possa assegnare il bit \itindex{sgid~bit} \acr{sgid} ad
  un file appartenente ad un gruppo per cui non si hanno diritti, questo viene
  automaticamente cancellato da \param{mode} (senza notifica di errore)
  qualora il gruppo del file non corrisponda a quelli associati al processo
  (la cosa non avviene quando l'\ids{UID} effettivo del processo è zero).
\end{enumerate}

Per alcuni filesystem\footnote{i filesystem più comuni (\textsl{ext2},
  \textsl{ext3}, \textsl{ext4}, \textsl{ReiserFS}) supportano questa
  caratteristica, che è mutuata da BSD.} è inoltre prevista un'ulteriore
misura di sicurezza, volta a scongiurare l'abuso dei \itindex{suid~bit} bit
\acr{suid} e \acr{sgid}; essa consiste nel cancellare automaticamente questi
bit dai permessi di un file qualora un processo che non appartenga
all'amministratore\footnote{per la precisione un processo che non dispone
  della \itindex{capabilities} capacità \const{CAP\_FSETID}, vedi
  sez.~\ref{sec:proc_capabilities}.} effettui una scrittura. In questo modo
anche se un utente malizioso scopre un file \acr{suid} su cui può scrivere,
un'eventuale modifica comporterà la perdita di questo privilegio.

Le funzioni \func{chmod} e \func{fchmod} ci permettono di modificare i
permessi di un file, resta però il problema di quali sono i permessi assegnati
quando il file viene creato. Le funzioni dell'interfaccia nativa di Unix, come
vedremo in sez.~\ref{sec:file_open}, permettono di indicare esplicitamente i
permessi di creazione di un file, ma questo non è possibile per le funzioni
dell'interfaccia standard ANSI C che non prevede l'esistenza di utenti e
gruppi, ed inoltre il problema si pone anche per l'interfaccia nativa quando i
permessi non vengono indicati esplicitamente. 

\itindbeg{umask} 

Per le funzioni dell'interfaccia standard ANSI C l'unico riferimento possibile
è quello della modalità di apertura del nuovo file (lettura/scrittura o sola
lettura), che però può fornire un valore che è lo stesso per tutti e tre i
permessi di sez.~\ref{sec:file_perm_overview} (cioè $666$ nel primo caso e
$222$ nel secondo). Per questo motivo il sistema associa ad ogni
processo\footnote{è infatti contenuta nel campo \var{umask} della struttura
  \kstruct{fs\_struct}, vedi fig.~\ref{fig:proc_task_struct}.}  una maschera
di bit, la cosiddetta \textit{umask}, che viene utilizzata per impedire che
alcuni permessi possano essere assegnati ai nuovi file in sede di creazione. I
bit indicati nella maschera vengono infatti cancellati dai permessi quando un
nuovo file viene creato.\footnote{l'operazione viene fatta sempre: anche
  qualora si indichi esplicitamente un valore dei permessi nelle funzioni di
  creazione che lo consentono, i permessi contenuti nella \textit{umask}
  verranno tolti.}

La funzione che permette di impostare il valore di questa maschera di
controllo è \funcd{umask}, ed il suo prototipo è:

\begin{funcproto}{
\fhead{stat.h}
\fdecl{mode\_t umask(mode\_t mask)}
\fdesc{Imposta la maschera dei permessi.} 
}

{La funzione ritorna ritorna il precedente valore della maschera, non sono
  previste condizioni di errore.}
\end{funcproto}

La funzione imposta maschera dei permessi dei bit al valore specificato
da \param{mask} (di cui vengono presi solo i 9 bit meno significativi).  In
genere si usa questa maschera per impostare un valore predefinito che escluda
preventivamente alcuni permessi (usualmente quello di scrittura per il gruppo
e gli altri, corrispondente ad un valore per \param{mask} pari a $022$).  In
questo modo è possibile cancellare automaticamente i permessi non voluti.  Di
norma questo valore viene impostato una volta per tutte al login a $022$, e
gli utenti non hanno motivi per modificarlo.

\itindend{umask} 


\subsection{La gestione della titolarità dei file}
\label{sec:file_ownership_management}

Vedremo in sez.~\ref{sec:file_base_func} con quali funzioni si possono creare
nuovi file, in tale occasione vedremo che è possibile specificare in sede di
creazione quali permessi applicare ad un file, però non si può indicare a
quale utente e gruppo esso deve appartenere.  Lo stesso problema si presenta
per la creazione di nuove directory (procedimento descritto in
sez.~\ref{sec:file_dir_creat_rem}).

Lo standard POSIX prescrive che l'\ids{UID} del nuovo file corrisponda
all'\ids{UID} effettivo del processo che lo crea; per il \ids{GID} invece
prevede due diverse possibilità:
\begin{itemize*}
\item il \ids{GID} del file corrisponde al \ids{GID} effettivo del processo.
\item il \ids{GID} del file corrisponde al \ids{GID} della directory in cui
  esso è creato.
\end{itemize*}
in genere BSD usa sempre la seconda possibilità, che viene per questo chiamata
semantica BSD. Linux invece segue quella che viene chiamata semantica SVr4; di
norma cioè il nuovo file viene creato, seguendo la prima opzione, con il
\ids{GID} del processo, se però la directory in cui viene creato il file ha il
bit \acr{sgid} impostato allora viene usata la seconda opzione.

Usare la semantica BSD ha il vantaggio che il \ids{GID} viene sempre
automaticamente propagato, restando coerente a quello della directory di
partenza, in tutte le sotto-directory. 

La semantica SVr4 offre la possibilità di scegliere, ma per ottenere lo stesso
risultato di coerenza che si ha con BSD necessita che quando si creano nuove
directory venga anche propagato anche il bit \acr{sgid}. Questo è il
comportamento predefinito del comando \cmd{mkdir}, ed è in questo modo ad
esempio che le varie distribuzioni assicurano che le sotto-directory create
nella home di un utente restino sempre con il \ids{GID} del gruppo primario
dello stesso.

La presenza del bit \acr{sgid} è inoltre molto comoda quando si hanno
directory contenenti file condivisi all'intero di un gruppo in cui possono
scrivere tutti i membri dello stesso, dato che assicura che i file che gli
utenti vi creano appartengano sempre allo stesso gruppo. Questo non risolve
però completamente i problemi di accesso da parte di altri utenti dello stesso
gruppo, in quanto i permessi assegnati al gruppo potrebbero non essere
sufficienti; in tal caso si deve aver cura di usare un valore di
\itindex{umask} \textit{umask} che ne lasci di sufficienti.\footnote{in tal
  caso si può assegnare agli utenti del gruppo una \textit{umask} di $002$,
  anche se la soluzione migliore in questo caso è usare una ACL di default
  (vedi sez.~\ref{sec:file_ACL}).}

Come avviene nel caso dei permessi il sistema fornisce anche delle funzioni,
\funcd{chown}, \funcd{fchown} e \funcd{lchown}, che permettono di cambiare sia
l'utente che il gruppo a cui un file appartiene; i rispettivi prototipi sono:

\begin{funcproto}{
\fhead{sys/types.h}
\fhead{sys/stat.h}
\fdecl{int chown(const char *path, uid\_t owner, gid\_t group)}
\fdecl{int fchown(int fd, uid\_t owner, gid\_t group)}
\fdecl{int lchown(const char *path, uid\_t owner, gid\_t group)}
\fdesc{Cambiano proprietario e gruppo proprietario di 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{EPERM}] l'\ids{UID} effettivo non corrisponde a quello del
    proprietario del file o non è zero, o utente e gruppo non sono validi
  \end{errlist}
  ed inoltre per tutte \errval{EROFS} e \errval{EIO}, per \func{chown}
  \errval{EFAULT}, \errval{ENAMETOOLONG}, \errval{ENOENT}, \errval{ENOMEM},
  \errval{ENOTDIR}, \errval{EACCES}, \errval{ELOOP}, per \func{fchown}
  \errval{EBADF} nel loro significato generico.}
\end{funcproto}

Le funzioni cambiano utente e gruppo di appartenenza di un file ai valori
specificati dalle variabili \param{owner} e \param{group}. Con Linux solo
l'amministratore\footnote{o in generale un processo con la
  \itindex{capabilities} capacità \const{CAP\_CHOWN}, vedi
  sez.~\ref{sec:proc_capabilities}.} può cambiare il proprietario di un file;
in questo viene seguita la semantica usata da BSD che non consente agli utenti
di assegnare i loro file ad altri utenti evitando eventuali aggiramenti delle
quote.  L'amministratore può cambiare sempre il gruppo di un file, il
proprietario può cambiare il gruppo solo dei file che gli appartengono e solo
se il nuovo gruppo è il suo gruppo primario o uno dei gruppi di cui fa parte.

La funzione \func{chown} segue i collegamenti simbolici, per operare
direttamente su un collegamento simbolico si deve usare la funzione
\func{lchown}.\footnote{fino alla versione 2.1.81 in Linux \func{chown} non
  seguiva i collegamenti simbolici, da allora questo comportamento è stato
  assegnato alla funzione \func{lchown}, introdotta per l'occasione, ed è
  stata creata una nuova \textit{system call} per \func{chown} che seguisse i
  collegamenti simbolici.} La funzione \func{fchown} opera su un file aperto,
essa è mutuata da BSD, ma non è nello standard POSIX.  Un'altra estensione
rispetto allo standard POSIX è che specificando -1 come valore
per \param{owner} e \param{group} i valori restano immutati.

Quando queste funzioni sono chiamate con successo da un processo senza i
privilegi di root entrambi i bit \itindex{suid~bit} \acr{suid} e
\itindex{sgid~bit} \acr{sgid} vengono cancellati. Questo non avviene per il
bit \acr{sgid} nel caso in cui esso sia usato (in assenza del corrispondente
permesso di esecuzione) per indicare che per il file è attivo il
\itindex{mandatory~locking} \textit{mandatory locking} (vedi
sez.~\ref{sec:file_mand_locking}).


\subsection{Un quadro d'insieme sui permessi}
\label{sec:file_riepilogo}

Avendo affrontato in maniera separata il comportamento delle varie funzioni
che operano sui permessi dei file ed avendo trattato in sezioni diverse il
significato dei singoli bit dei permessi, vale la pena di fare un riepilogo in
cui si riassumano le caratteristiche di ciascuno di essi, in modo da poter
fornire un quadro d'insieme.

\begin{table}[!htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|c|c|c|c|c|c|c|c|c|c|c|c|l|}
    \hline
    \multicolumn{3}{|c|}{special}&
    \multicolumn{3}{|c|}{user}&
    \multicolumn{3}{|c|}{group}&
    \multicolumn{3}{|c|}{other}&
    \multirow{2}{*}{\textbf{Significato per i file}} \\
    \cline{1-12}
    \texttt{s}&\texttt{s}&\texttt{t}&
    \texttt{r}&\texttt{w}&\texttt{x}&
    \texttt{r}&\texttt{w}&\texttt{x}&
    \texttt{r}&\texttt{w}&\texttt{x}& \\
    \hline
    \hline
   1&-&-&-&-&1&-&-&-&-&-&-&Eseguito conferisce l'\ids{UID} effettivo dell'utente.\\
   -&1&-&-&-&1&-&-&-&-&-&-&Eseguito conferisce il \ids{GID} effettivo del gruppo.\\
   -&1&-&-&-&0&-&-&-&-&-&-&Il \itindex{mandatory~locking} 
                           \textit{mandatory locking} è abilitato.\\
   -&-&1&-&-&-&-&-&-&-&-&-&Non utilizzato.\\
   -&-&-&1&-&-&-&-&-&-&-&-&Permesso di lettura per l'utente.\\
   -&-&-&-&1&-&-&-&-&-&-&-&Permesso di scrittura per l'utente.\\
   -&-&-&-&-&1&-&-&-&-&-&-&Permesso di esecuzione per l'utente.\\
   -&-&-&-&-&-&1&-&-&-&-&-&Permesso di lettura per il gruppo.\\
   -&-&-&-&-&-&-&1&-&-&-&-&Permesso di scrittura per il gruppo.\\
   -&-&-&-&-&-&-&-&1&-&-&-&Permesso di esecuzione per il gruppo.\\
   -&-&-&-&-&-&-&-&-&1&-&-&Permesso di lettura per tutti gli altri.\\
   -&-&-&-&-&-&-&-&-&-&1&-&Permesso di scrittura per tutti gli altri.\\
   -&-&-&-&-&-&-&-&-&-&-&1&Permesso di esecuzione per tutti gli altri.\\
    \hline
    \hline
    \multicolumn{3}{|c|}{special}&
    \multicolumn{3}{|c|}{user}&
    \multicolumn{3}{|c|}{group}&
    \multicolumn{3}{|c|}{other}&
    \multirow{2}{*}{\textbf{Significato per le directory}} \\
    \cline{1-12}
    \texttt{s}&\texttt{s}&\texttt{t}&
    \texttt{r}&\texttt{w}&\texttt{x}&
    \texttt{r}&\texttt{w}&\texttt{x}&
    \texttt{r}&\texttt{w}&\texttt{x}& \\
    \hline
    \hline
    1&-&-&-&-&-&-&-&-&-&-&-&Non utilizzato.\\
    -&1&-&-&-&-&-&-&-&-&-&-&Propaga il gruppo ai nuovi file creati.\\
    -&-&1&-&-&-&-&-&-&-&-&-&Solo il proprietario di un file può rimuoverlo.\\
    -&-&-&1&-&-&-&-&-&-&-&-&Permesso di visualizzazione per l'utente.\\
    -&-&-&-&1&-&-&-&-&-&-&-&Permesso di aggiornamento per l'utente.\\
    -&-&-&-&-&1&-&-&-&-&-&-&Permesso di attraversamento per l'utente.\\
    -&-&-&-&-&-&1&-&-&-&-&-&Permesso di visualizzazione per il gruppo.\\
    -&-&-&-&-&-&-&1&-&-&-&-&Permesso di aggiornamento per il gruppo.\\
    -&-&-&-&-&-&-&-&1&-&-&-&Permesso di attraversamento per il gruppo.\\
    -&-&-&-&-&-&-&-&-&1&-&-&Permesso di visualizzazione per tutti gli altri.\\
    -&-&-&-&-&-&-&-&-&-&1&-&Permesso di aggiornamento per tutti gli altri.\\
    -&-&-&-&-&-&-&-&-&-&-&1&Permesso di attraversamento per tutti gli altri.\\
    \hline
  \end{tabular}
  \caption{Tabella riassuntiva del significato dei bit dei permessi per un
    file e directory.} 
  \label{tab:file_fileperm_bits}
\end{table}

Nella parte superiore di tab.~\ref{tab:file_fileperm_bits} si è riassunto il
significato dei vari bit dei permessi per un file ordinario; per quanto
riguarda l'applicazione dei permessi per proprietario, gruppo ed altri si
ricordi quanto illustrato in sez.~\ref{sec:file_perm_overview}.  Per
compattezza, nella tabella si sono specificati i bit di \itindex{suid~bit}
\textit{suid}, \itindex{sgid~bit} \textit{sgid} e \textit{sticky}
\itindex{sticky~bit} con la notazione illustrata anche in
fig.~\ref{fig:file_perm_bit}.  Nella parte inferiore si sono invece riassunti
i significati dei vari bit dei permessi per una directory; anche in questo
caso si è riapplicato ai bit di \itindex{suid~bit} \textit{suid},
\itindex{sgid~bit} \textit{sgid} e \textit{sticky} \itindex{sticky~bit} la
notazione illustrata in fig.~\ref{fig:file_perm_bit}.

Si ricordi infine che i permessi non hanno alcun significato per i
collegamenti simbolici, mentre per i \index{file!di~dispositivo} file di
dispositivo hanno senso soltanto i permessi di lettura e scrittura, che si
riflettono sulla possibilità di compiere dette operazioni sul dispositivo
stesso.

Nella tabella si è indicato con il carattere ``-'' il fatto che il valore del
bit in questione non è influente rispetto a quanto indicato nella riga della
tabella; la descrizione del significato fa riferimento soltanto alla
combinazione di bit per i quali è stato riportato esplicitamente un valore.
Si rammenti infine che il valore dei bit dei permessi non ha alcun effetto
qualora il processo possieda i privilegi di amministratore.


\section{Caratteristiche e funzionalità avanzate}
\label{sec:file_dir_advances}

Tratteremo qui alcune caratteristiche e funzionalità avanzate della gestione
di file e directory, affrontando anche una serie di estensioni
dell'interfaccia classica dei sistemi unix-like, principalmente utilizzate a
scopi di sicurezza, che sono state introdotte nelle versioni più recenti di
Linux.

\subsection{Gli attributi estesi}
\label{sec:file_xattr}

\itindbeg{Extended~Attributes}

Nelle sezioni precedenti abbiamo trattato in dettaglio le varie informazioni
che il sistema mantiene negli \itindex{inode} \textit{inode}, e le varie
funzioni che permettono di modificarle.  Si sarà notato come in realtà queste
informazioni siano estremamente ridotte.  Questo è dovuto al fatto che Unix
origina negli anni '70, quando le risorse di calcolo e di spazio disco erano
minime. Con il venir meno di queste restrizioni è incominciata ad emergere
l'esigenza di poter associare ai file delle ulteriori informazioni astratte
(quelli che vengono chiamati i \textsl{meta-dati}) che però non potevano
trovare spazio nei dati classici mantenuti negli \itindex{inode}
\textit{inode}.

Per risolvere questo problema alcuni sistemi unix-like (e fra questi anche
Linux) hanno introdotto un meccanismo generico, detto \textit{Extended
  Attributes} che consenta di associare delle informazioni ai singoli
file.\footnote{l'uso più comune è quello della ACL, che tratteremo nella
  prossima sezione.} Gli \textsl{attributi estesi} non sono altro che delle
coppie nome/valore che sono associate permanentemente ad un oggetto sul
filesystem, analoghi di quello che sono le variabili di ambiente (vedi
sez.~\ref{sec:proc_environ}) per un processo.

Altri sistemi (come Solaris, MacOS e Windows) hanno adottato un meccanismo
diverso in cui ad un file sono associati diversi flussi di dati, su cui
possono essere mantenute ulteriori informazioni, che possono essere accedute
con le normali operazioni di lettura e scrittura. Questi non vanno confusi con
gli \textit{Extended Attributes} (anche se su Solaris hanno lo stesso nome),
che sono un meccanismo molto più semplice, che pur essendo limitato (potendo
contenere solo una quantità limitata di informazione) hanno il grande
vantaggio di essere molto più semplici da realizzare, più
efficienti,\footnote{cosa molto importante, specie per le applicazioni che
  richiedono una gran numero di accessi, come le ACL.} e di garantire
l'atomicità di tutte le operazioni.

In Linux gli attributi estesi sono sempre associati al singolo \itindex{inode}
\textit{inode} e l'accesso viene sempre eseguito in forma atomica, in lettura
il valore corrente viene scritto su un buffer in memoria, mentre la scrittura
prevede che ogni valore precedente sia sovrascritto.

Si tenga presente che non tutti i filesystem supportano gli \textit{Extended
  Attributes}; al momento della scrittura di queste dispense essi sono
presenti solo sui vari \textsl{extN}, \textsl{ReiserFS}, \textsl{JFS},
\textsl{XFS} e \textsl{Btrfs}.\footnote{l'elenco è aggiornato a Luglio 2011.}
Inoltre a seconda della implementazione ci possono essere dei limiti sulla
quantità di attributi che si possono utilizzare.\footnote{ad esempio nel caso
  di \textsl{ext2} ed \textsl{ext3} è richiesto che essi siano contenuti
  all'interno di un singolo blocco (pertanto con dimensioni massime pari a
  1024, 2048 o 4096 byte a seconda delle dimensioni di quest'ultimo impostate
  in fase di creazione del filesystem), mentre con \textsl{XFS} non ci sono
  limiti ed i dati vengono memorizzati in maniera diversa (nell'\textit{inode}
  stesso, in un blocco a parte, o in una struttura ad albero dedicata) per
  mantenerne la scalabilità.} Infine lo spazio utilizzato per mantenere gli
attributi estesi viene tenuto in conto per il calcolo delle quote di utente e
gruppo proprietari del file.

Come meccanismo per mantenere informazioni aggiuntive associate al singolo
file, gli \textit{Extended Attributes} possono avere usi anche molto diversi
fra loro.  Per poterli distinguere allora sono stati suddivisi in
\textsl{classi}, a cui poter applicare requisiti diversi per l'accesso e la
gestione. Per questo motivo il nome di un attributo deve essere sempre
specificato nella forma \texttt{namespace.attribute}, dove \texttt{namespace}
fa riferimento alla classe a cui l'attributo appartiene, mentre
\texttt{attribute} è il nome ad esso assegnato. In tale forma il nome di un
attributo esteso deve essere univoco. Al momento\footnote{della scrittura di
  questa sezione, kernel 2.6.23, ottobre 2007.} sono state definite le quattro
classi di attributi riportate in tab.~\ref{tab:extended_attribute_class}.

\begin{table}[htb]
  \centering
  \footnotesize
  \begin{tabular}{|l|p{12cm}|}
    \hline
    \textbf{Nome} & \textbf{Descrizione} \\
    \hline
    \hline
    \texttt{security}&Gli \textit{extended security attributes}: vengono
                      utilizzati dalle estensioni di sicurezza del kernel (i
                      \itindex{Linux~Security~Modules} \textit{Linux 
                        Security Modules}), per le realizzazione di meccanismi
                      evoluti di controllo di accesso come \index{SELinux}
                      SELinux o le \textit{capabilities} dei file di
                      sez.~\ref{sec:proc_capabilities}.\\ 
    \texttt{system} & Gli \textit{extended security attributes}: sono usati
                      dal kernel per memorizzare dati di sistema associati ai
                      file come le \itindex{Access~Control~List~(ACL)} ACL (vedi
                      sez.~\ref{sec:file_ACL}) o le \itindex{capabilities}
                      \textit{capabilities} (vedi
                      sez.~\ref{sec:proc_capabilities}).\\
    \texttt{trusted}& I \textit{trusted extended attributes}: vengono
                      utilizzati per poter realizzare in user space 
                      meccanismi che consentano di mantenere delle
                      informazioni sui file che non devono essere accessibili
                      ai processi ordinari.\\
    \texttt{user}   & Gli \textit{extended user attributes}: utilizzati per
                      mantenere informazioni aggiuntive sui file (come il
                      \textit{mime-type}, la codifica dei caratteri o del
                      file) accessibili dagli utenti.\\
    \hline
  \end{tabular}
  \caption{I nomi utilizzati valore di \texttt{namespace} per distinguere le
    varie classi di \textit{Extended Attributes}.}
  \label{tab:extended_attribute_class}
\end{table}


Dato che uno degli usi degli \textit{Extended Attributes} è quello che li
impiega per realizzare delle estensioni (come le
\itindex{Access~Control~List~(ACL)} ACL, \index{SELinux} SELinux, ecc.) al
tradizionale meccanismo dei controlli di accesso di Unix, l'accesso ai loro
valori viene regolato in maniera diversa a seconda sia della loro classe sia
di quali, fra le estensioni che li utilizzano, sono poste in uso. In
particolare, per ciascuna delle classi riportate in
tab.~\ref{tab:extended_attribute_class}, si hanno i seguenti casi:
\begin{basedescript}{\desclabelwidth{1.7cm}\desclabelstyle{\nextlinelabel}}
\item[\texttt{security}] L'accesso agli \textit{extended security attributes}
  dipende dalle politiche di sicurezza stabilite da loro stessi tramite
  l'utilizzo di un sistema di controllo basato sui
  \itindex{Linux~Security~Modules} \textit{Linux Security Modules} (ad esempio
  \index{SELinux} SELinux). Pertanto l'accesso in lettura o scrittura dipende
  dalle politiche di sicurezza implementate all'interno dal modulo di
  sicurezza che si sta utilizzando al momento (ciascuno avrà le sue). Se non è
  stato caricato nessun modulo di sicurezza l'accesso in lettura sarà
  consentito a tutti i processi, mentre quello in scrittura solo ai processi
  con privilegi amministrativi dotati della \itindex{capabilities}
  \textit{capability} \const{CAP\_SYS\_ADMIN}.

\item[\texttt{system}] Anche l'accesso agli \textit{extended system
    attributes} dipende dalle politiche di accesso che il kernel realizza
  anche utilizzando gli stessi valori in essi contenuti. Ad esempio nel caso
  delle \itindex{Access~Control~List~(ACL)} ACL l'accesso è consentito in
  lettura ai processi che hanno la capacità di eseguire una ricerca sul file
  (cioè hanno il permesso di lettura sulla directory che contiene il file) ed
  in scrittura al proprietario del file o ai processi dotati della
  \textit{capability} \itindex{capabilities}
  \const{CAP\_FOWNER}.\footnote{vale a dire una politica di accesso analoga a
    quella impiegata per gli ordinari permessi dei file.}

\item[\texttt{trusted}] L'accesso ai \textit{trusted extended attributes}, sia
  per la lettura che per la scrittura, è consentito soltanto ai processi con
  privilegi amministrativi dotati della \itindex{capabilities}
  \textit{capability} \const{CAP\_SYS\_ADMIN}. In questo modo si possono
  utilizzare questi attributi per realizzare in user space dei meccanismi di
  controllo che accedono ad informazioni non disponibili ai processi ordinari.

\item[\texttt{user}] L'accesso agli \textit{extended user attributes} è
  regolato dai normali permessi dei file: occorre avere il permesso di lettura
  per leggerli e quello di scrittura per scriverli o modificarli. Dato l'uso
  di questi attributi si è scelto di applicare al loro accesso gli stessi
  criteri che si usano per l'accesso al contenuto dei file (o delle directory)
  cui essi fanno riferimento. Questa scelta vale però soltanto per i file e le
  directory ordinarie, se valesse in generale infatti si avrebbe un serio
  problema di sicurezza dato che esistono diversi oggetti sul filesystem per i
  quali è normale avere avere il permesso di scrittura consentito a tutti gli
  utenti, come i collegamenti simbolici, o alcuni \index{file!di~dispositivo}
  file di dispositivo come \texttt{/dev/null}. Se fosse possibile usare su di
  essi gli \textit{extended user attributes} un utente qualunque potrebbe
  inserirvi dati a piacere.\footnote{la cosa è stata notata su XFS, dove
    questo comportamento permetteva, non essendovi limiti sullo spazio
    occupabile dagli \textit{Extended Attributes}, di bloccare il sistema
    riempiendo il disco.}

  La semantica del controllo di accesso indicata inoltre non avrebbe alcun
  senso al di fuori di file e directory: i permessi di lettura e scrittura per
  un \index{file!di~dispositivo} file di dispositivo attengono alle capacità
  di accesso al dispositivo sottostante,\footnote{motivo per cui si può
    formattare un disco anche se \texttt{/dev} è su un filesystem in sola
    lettura.} mentre per i collegamenti simbolici questi vengono semplicemente
  ignorati: in nessuno dei due casi hanno a che fare con il contenuto del
  file, e nella discussione relativa all'uso degli \textit{extended user
    attributes} nessuno è mai stato capace di indicare una qualche forma
  sensata di utilizzo degli stessi per collegamenti simbolici o
  \index{file!di~dispositivo} file di dispositivo, e neanche per le fifo o i
  socket.  Per questo motivo essi sono stati completamente disabilitati per
  tutto ciò che non sia un file regolare o una directory.\footnote{si può
    verificare la semantica adottata consultando il file \texttt{fs/xattr.c}
    dei sorgenti del kernel.} Inoltre per le directory è stata introdotta una
  ulteriore restrizione, dovuta di nuovo alla presenza ordinaria di permessi
  di scrittura completi su directory come \texttt{/tmp}. Per questo motivo,
  per evitare eventuali abusi, se una directory ha lo \itindex{sticky~bit}
  \textit{sticky bit} attivo sarà consentito scrivere i suoi \textit{extended
    user attributes} soltanto se si è proprietari della stessa, o si hanno i
  privilegi amministrativi della capability \itindex{capabilities}
  \const{CAP\_FOWNER}.
\end{basedescript}

Le funzioni per la gestione degli attributi estesi, come altre funzioni di
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
esplicitamente l'uso della suddetta libreria invocando il compilatore con
l'opzione \texttt{-lattr}.  

Per poter leggere gli attributi estesi sono disponibili tre diverse funzioni,
\funcd{getxattr}, \funcd{lgetxattr} e \funcd{fgetxattr}, che consentono
rispettivamente di richiedere gli attributi relativi a un file, a un
collegamento simbolico e ad un file descriptor; i rispettivi prototipi sono:

\begin{funcproto}{
\fhead{sys/types.h}
\fhead{attr/xattr.h}
\fdecl{ssize\_t getxattr(const char *path, const char *name, void *value,
  size\_t size)}
\fdecl{ssize\_t lgetxattr(const char *path, const char *name, void *value,
  size\_t size)}
\fdecl{ssize\_t fgetxattr(int filedes, const char *name, void *value,
  size\_t size)}
\fdesc{Leggono il valore di un attributo esteso.} 
}

{Le funzioni ritornano un intero positivo che indica la dimensione
  dell'attributo richiesto in caso di successo e $-1$ per un errore, nel qual
  caso \var{errno} assumerà uno dei valori:
  \begin{errlist}
  \item[\errcode{ENOATTR}] l'attributo richiesto non esiste.
  \item[\errcode{ERANGE}] la dimensione \param{size} del buffer \param{value}
    non è sufficiente per contenere il risultato.
  \item[\errcode{ENOTSUP}] gli attributi estesi non sono supportati dal
    filesystem o sono disabilitati.
  \end{errlist}
  ed inoltre tutti gli errori delle analoghe della famiglia \func{stat} con lo
  stesso significato ed in particolare \errcode{EPERM} se non si hanno i
  permessi di accesso all'attributo.}
\end{funcproto}

Le funzioni \func{getxattr} e \func{lgetxattr} prendono come primo argomento
un \textit{pathname} che indica il file di cui si vuole richiedere un
attributo, la sola differenza è che la seconda, se il \textit{pathname} indica
un collegamento simbolico, restituisce gli attributi di quest'ultimo e non
quelli del file a cui esso fa riferimento. La funzione \func{fgetxattr} prende
invece come primo argomento un numero di file descriptor, e richiede gli
attributi del file ad esso associato.

Tutte e tre le funzioni richiedono di specificare nell'argomento \param{name}
il nome dell'attributo di cui si vuole ottenere il valore. Il nome deve essere
indicato comprensivo di prefisso del \textit{namespace} cui appartiene (uno
dei valori di tab.~\ref{tab:extended_attribute_class}) nella forma
\texttt{namespace.attributename}, come stringa terminata da un carattere NUL.
Il suo valore verrà restituito nel buffer puntato dall'argomento \param{value}
per una dimensione massima di \param{size} byte;\footnote{gli attributi estesi
  possono essere costituiti arbitrariamente da dati testuali o binari.}  se
quest'ultima non è sufficiente si avrà un errore di \errcode{ERANGE}.

Per evitare di dover indovinare la dimensione di un attributo per tentativi si
può eseguire una interrogazione utilizzando un valore nullo per \param{size};
in questo caso non verrà letto nessun dato, ma verrà restituito come valore di
ritorno della funzione chiamata la dimensione totale dell'attributo esteso
richiesto, che si potrà usare come stima per allocare un buffer di dimensioni
sufficienti.\footnote{si parla di stima perché anche se le funzioni
  restituiscono la dimensione esatta dell'attributo al momento in cui sono
  eseguite, questa potrebbe essere modificata in qualunque momento da un
  successivo accesso eseguito da un altro processo.}

Un secondo gruppo di funzioni è quello che consente di impostare il valore di
un attributo esteso, queste sono \funcd{setxattr}, \funcd{lsetxattr} e
\funcd{fsetxattr}, e consentono di operare rispettivamente su un file, su un
collegamento simbolico o specificando un file descriptor; i loro prototipi sono:

\begin{funcproto}{
\fhead{sys/types.h}
\fhead{attr/xattr.h}
\fdecl{int setxattr(const char *path, const char *name, const void *value,
  size\_t size, int flags)} 
\fdecl{int lsetxattr(const char *path, const char *name, const void *value,
  size\_t size, int flags)} 
\fdecl{int fsetxattr(int filedes, const char *name, const void *value, size\_t
  size, int flags)} 
\fdesc{Impostano il valore di un attributo esteso.} 
}

{Le funzioni ritornano un $0$ in caso di successo e $-1$ per un errore, nel qual
  caso \var{errno} assumerà uno dei valori:
  \begin{errlist}
  \item[\errcode{ENOATTR}] si è usato il flag \const{XATTR\_REPLACE} e
    l'attributo richiesto non esiste.
  \item[\errcode{EEXIST}] si è usato il flag \const{XATTR\_CREATE} ma
    l'attributo esiste già.
  \item[\errcode{ENOTSUP}] gli attributi estesi non sono supportati dal
    filesystem o sono disabilitati.
  \end{errlist}
  ed inoltre tutti gli errori delle analoghe della famiglia \func{stat} con lo
  stesso significato ed in particolare \errcode{EPERM} se non si hanno i
  permessi di accesso all'attributo.}
\end{funcproto}

Le tre funzioni prendono come primo argomento un valore adeguato al loro
scopo, usato in maniera del tutto identica a quanto visto in precedenza per le
analoghe che leggono gli attributi estesi. Il secondo argomento \param{name}
deve indicare, anche in questo caso con gli stessi criteri appena visti per le
analoghe \func{getxattr}, \func{lgetxattr} e \func{fgetxattr}, il nome
(completo di suffisso) dell'attributo su cui si vuole operare. 

Il valore che verrà assegnato all'attributo dovrà essere preparato nel buffer
puntato da \param{value}, e la sua dimensione totale (in byte) sarà indicata
dall'argomento \param{size}. Infine l'argomento \param{flag} consente di
controllare le modalità di sovrascrittura dell'attributo esteso, esso può
prendere due valori: con \const{XATTR\_REPLACE} si richiede che l'attributo
esista, nel qual caso verrà sovrascritto, altrimenti si avrà errore, mentre
con \const{XATTR\_CREATE} si richiede che l'attributo non esista, nel qual
caso verrà creato, altrimenti si avrà errore ed il valore attuale non sarà
modificato.  Utilizzando per \param{flag} un valore nullo l'attributo verrà
modificato se è già presente, o creato se non c'è.

Le funzioni finora illustrate permettono di leggere o scrivere gli attributi
estesi, ma sarebbe altrettanto utile poter vedere quali sono gli attributi
presenti; a questo provvedono le funzioni \funcd{listxattr},
\funcd{llistxattr} e \funcd{flistxattr} i cui prototipi sono:

\begin{funcproto}{
\fhead{sys/types.h}
\fhead{attr/xattr.h}
\fdecl{ssize\_t listxattr(const char *path, char *list, size\_t size)} 
\fdecl{ssize\_t llistxattr(const char *path, char *list, size\_t size)} 
\fdecl{ssize\_t flistxattr(int filedes, char *list, size\_t size)} 
\fdesc{Leggono la lista degli attributi estesi di un file.} 
}

{Le funzioni ritornano un intero positivo che indica la dimensione della lista
  in caso di successo e $-1$ per un errore, nel qual caso \var{errno} assumerà
  uno dei valori:
  \begin{errlist}
  \item[\errcode{ERANGE}] la dimensione \param{size} del buffer \param{value}
    non è sufficiente per contenere il risultato.
  \item[\errcode{ENOTSUP}] gli attributi estesi non sono supportati dal
    filesystem o sono disabilitati.
  \end{errlist}
  ed inoltre tutti gli errori delle analoghe della famiglia \func{stat} con lo
  stesso significato ed in particolare \errcode{EPERM} se non si hanno i
  permessi di accesso all'attributo.}
\end{funcproto}

Come per le precedenti le tre funzioni leggono gli attributi rispettivamente
di un file, un collegamento simbolico o specificando un file descriptor, da
specificare con il loro primo argomento. Gli altri due argomenti, identici per
tutte e tre, indicano rispettivamente il puntatore \param{list} al buffer dove
deve essere letta la lista e la dimensione \param{size} di quest'ultimo.

La lista viene fornita come sequenza non ordinata dei nomi dei singoli
attributi estesi (sempre comprensivi del prefisso della loro classe) ciascuno
dei quali è terminato da un carattere nullo. I nomi sono inseriti nel buffer
uno di seguito all'altro. Il valore di ritorno della funzione indica la
dimensione totale della lista in byte.

Come per le funzioni di lettura dei singoli attributi se le dimensioni del
buffer non sono sufficienti si avrà un errore, ma è possibile ottenere dal
valore di ritorno della funzione una stima della dimensione totale della lista
usando per \param{size} un valore nullo. 

Infine per rimuovere semplicemente un attributo esteso, si ha a disposizione
un ultimo gruppo di funzioni: \funcd{removexattr}, \funcd{lremovexattr} e
\funcd{fremovexattr}; i rispettivi prototipi sono:

\begin{funcproto}{
\fhead{sys/types.h}
\fhead{attr/xattr.h}
\fdecl{int removexattr(const char *path, const char *name)} 
\fdecl{int lremovexattr(const char *path, const char *name)} 
\fdecl{int fremovexattr(int filedes, const char *name)} 
\fdesc{Rimuovono un attributo esteso di un file.} 
}

{Le funzioni ritornano $0$ in caso di successo e $-1$ per un errore, nel qual
  caso \var{errno} assumerà uno dei valori:
  \begin{errlist}
  \item[\errcode{ENOATTR}] l'attributo richiesto non esiste.
  \item[\errcode{ENOTSUP}] gli attributi estesi non sono supportati dal
    filesystem o sono disabilitati.
  \end{errlist}
  ed inoltre tutti gli errori delle analoghe della famiglia \func{stat} con lo
  stesso significato ed in particolare \errcode{EPERM} se non si hanno i
  permessi di accesso all'attributo.}
\end{funcproto}

Le tre funzioni rimuovono l'attributo esteso indicato dall'argomento
\param{name} rispettivamente di un file, un collegamento simbolico o
specificando un file descriptor, da specificare con il loro primo argomento.
Anche in questo caso l'argomento \param{name} deve essere specificato con le
modalità già illustrate in precedenza per le altre funzioni relative agli
attributi estesi.

\itindend{Extended~Attributes}


\subsection{Le \textit{Access  Control List}}
\label{sec:file_ACL}

% la documentazione di sistema è nei pacchetti libacl1-dev e acl 
% vedi anche http://www.suse.de/~agruen/acl/linux-acls/online/

\itindbeg{Access~Control~List~(ACL)}

Il modello classico dei permessi di Unix, per quanto funzionale ed efficiente,
è comunque piuttosto limitato e per quanto possa aver coperto per lunghi anni
le esigenze più comuni con un meccanismo semplice e potente, non è in grado di
rispondere in maniera adeguata a situazioni che richiedono una gestione
complessa dei permessi di accesso.\footnote{già un requisito come quello di
  dare accesso in scrittura ad alcune persone ed in sola lettura ad altre non
  si può soddisfare in maniera semplice.}

Per questo motivo erano state progressivamente introdotte nelle varie versioni
di Unix dei meccanismi di gestione dei permessi dei file più flessibili, nella
forma delle cosiddette \textit{Access Control List} (indicate usualmente con
la sigla ACL).  Nello sforzo di standardizzare queste funzionalità era stato
creato un gruppo di lavoro il cui scopo era estendere lo standard POSIX 1003
attraverso due nuovi insiemi di specifiche, la POSIX 1003.1e per l'interfaccia
di programmazione e la POSIX 1003.2c per i comandi di shell.

Gli obiettivi erano però forse troppo ambizioni, e nel gennaio del 1998 i
finanziamenti vennero ritirati senza che si fosse arrivati alla definizione di
uno standard, dato però che una parte della documentazione prodotta era di
alta qualità venne deciso di rilasciare al pubblico la diciassettesima bozza
del documento, quella che va sotto il nome di \textit{POSIX 1003.1e Draft 17},
che è divenuta la base sulla quale si definiscono le cosiddette \textit{Posix
  ACL}.

A differenza di altri sistemi (ad esempio FreeBSD) nel caso di Linux si è
scelto di realizzare le ACL attraverso l'uso degli
\itindex{Extended~Attributes} \textit{Extended Attributes} (appena trattati in
sez.~\ref{sec:file_xattr}), e fornire tutte le relative funzioni di gestione
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 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}
  per i file di sviluppo.}  pertanto se un programma le utilizza si dovrà
indicare esplicitamente l'uso della libreria \texttt{libacl} invocando il
compilatore con l'opzione \texttt{-lacl}. Si tenga presente inoltre che per
poterle utilizzare le ACL devono essere attivate esplicitamente montando il
filesystem\footnote{che deve supportarle, ma questo è ormai vero per
  praticamente tutti i filesystem più comuni, con l'eccezione di NFS per il
  quale esiste però un supporto sperimentale.} su cui le si vogliono
utilizzare con l'opzione \texttt{acl} attiva. Dato che si tratta di una
estensione è infatti opportuno utilizzarle soltanto laddove siano necessarie.

Una ACL è composta da un insieme di voci, e ciascuna voce è a sua volta
costituita da un \textsl{tipo}, da un eventuale
\textsl{qualificatore},\footnote{deve essere presente soltanto per le voci di
  tipo \const{ACL\_USER} e \const{ACL\_GROUP}.} e da un insieme di permessi.
Ad ogni oggetto sul filesystem si può associare una ACL che ne governa i
permessi di accesso, detta \textit{access ACL}.  Inoltre per le directory si
può impostare una ACL aggiuntiva, detta \textit{default ACL}, che serve ad
indicare quale dovrà essere la ACL assegnata di default nella creazione di un
file all'interno della directory stessa. Come avviene per i permessi le ACL
possono essere impostate solo del proprietario del file, o da un processo con
la capability \itindex{capabilities} \const{CAP\_FOWNER}.

\begin{table}[htb]
  \centering
  \footnotesize
  \begin{tabular}{|l|p{8cm}|}
    \hline
    \textbf{Tipo} & \textbf{Descrizione} \\
    \hline
    \hline
    \const{ACL\_USER\_OBJ} & voce che contiene i diritti di accesso del
                             proprietario del file.\\
    \const{ACL\_USER}      & voce che contiene i diritti di accesso per
                             l'utente indicato dal rispettivo
                             qualificatore.\\  
    \const{ACL\_GROUP\_OBJ}& voce che contiene i diritti di accesso del
                             gruppo proprietario del file.\\
    \const{ACL\_GROUP}     & voce che contiene i diritti di accesso per
                             il gruppo indicato dal rispettivo
                             qualificatore.\\
    \const{ACL\_MASK}      & voce che contiene la maschera dei massimi
                             permessi di accesso che possono essere garantiti
                             da voci del tipo \const{ACL\_USER},
                             \const{ACL\_GROUP} e \const{ACL\_GROUP\_OBJ}.\\
    \const{ACL\_OTHER}     & voce che contiene i diritti di accesso di chi
                             non corrisponde a nessuna altra voce dell'ACL.\\
    \hline
  \end{tabular}
  \caption{Le costanti che identificano i tipi delle voci di una ACL.}
  \label{tab:acl_tag_types}
\end{table}

L'elenco dei vari tipi di voci presenti in una ACL, con una breve descrizione
del relativo significato, è riportato in tab.~\ref{tab:acl_tag_types}. Tre di
questi tipi, \const{ACL\_USER\_OBJ}, \const{ACL\_GROUP\_OBJ} e
\const{ACL\_OTHER}, corrispondono direttamente ai tre permessi ordinari dei
file (proprietario, gruppo proprietario e tutti gli altri) e per questo una
ACL valida deve sempre contenere una ed una sola voce per ciascuno di questi
tipi.

Una ACL può poi contenere un numero arbitrario di voci di tipo
\const{ACL\_USER} e \const{ACL\_GROUP}, ciascuna delle quali indicherà i
permessi assegnati all'utente e al gruppo indicato dal relativo qualificatore;
ovviamente ciascuna di queste voci dovrà fare riferimento ad un utente o ad un
gruppo diverso, e non corrispondenti a quelli proprietari del file. Inoltre se
in una ACL esiste una voce di uno di questi due tipi è obbligatoria anche la
presenza di una ed una sola voce di tipo \const{ACL\_MASK}, che negli altri
casi è opzionale.

Quest'ultimo tipo di voce contiene la maschera dei permessi che possono essere
assegnati tramite voci di tipo \const{ACL\_USER}, \const{ACL\_GROUP} e
\const{ACL\_GROUP\_OBJ}; se in una di queste voci si fosse specificato un
permesso non presente in \const{ACL\_MASK} questo verrebbe ignorato. L'uso di
una ACL di tipo \const{ACL\_MASK} è di particolare utilità quando essa
associata ad una \textit{default ACL} su una directory, in quanto i permessi
così specificati verranno ereditati da tutti i file creati nella stessa
directory. Si ottiene così una sorta di \itindex{umask} \textit{umask}
associata ad un oggetto sul filesystem piuttosto che a un processo.

Dato che le ACL vengono a costituire una estensione dei permessi ordinari, uno
dei problemi che si erano posti nella loro standardizzazione era appunto
quello della corrispondenza fra questi e le ACL. Come accennato i permessi
ordinari vengono mappati le tre voci di tipo \const{ACL\_USER\_OBJ},
\const{ACL\_GROUP\_OBJ} e \const{ACL\_OTHER} che devono essere presenti in
qualunque ACL; un cambiamento ad una di queste voci viene automaticamente
riflesso sui permessi ordinari dei file\footnote{per permessi ordinari si
  intende quelli mantenuti \itindex{inode} nell'\textit{inode}, che devono
  restare dato che un filesystem può essere montato senza abilitare le ACL.} e
viceversa. In realtà la mappatura è diretta solo per le voci
\const{ACL\_USER\_OBJ} e \const{ACL\_OTHER}, nel caso di
\const{ACL\_GROUP\_OBJ} questo vale soltanto se non è presente una voce di
tipo \const{ACL\_MASK}, se invece questa è presente verranno tolti dai
permessi di \const{ACL\_GROUP\_OBJ} tutti quelli non presenti in
\const{ACL\_MASK}.\footnote{questo diverso comportamento a seconda delle
  condizioni è stato introdotto dalla standardizzazione \textit{POSIX 1003.1e
    Draft 17} per mantenere il comportamento invariato sui sistemi dotati di
  ACL per tutte quelle applicazioni che sono conformi soltanto all'ordinario
  standard \textit{POSIX 1003.1}.}

Un secondo aspetto dell'incidenza delle ACL sul comportamento del sistema è
quello relativo alla creazione di nuovi file,\footnote{o oggetti sul
  filesystem, il comportamento discusso vale per le funzioni \func{open} e
  \func{creat} (vedi sez.~\ref{sec:file_open}), \func{mkdir} (vedi
  sez.~\ref{sec:file_dir_creat_rem}), \func{mknod} e \func{mkfifo} (vedi
  sez.~\ref{sec:file_mknod}).} che come accennato può essere modificato dalla
presenza di una \textit{default ACL} sulla directory che contiene quel file.
Se questa non c'è valgono le regole usuali illustrate in
sez.~\ref{sec:file_perm_management}, per cui essi sono determinati dalla
\itindex{umask} \textit{umask} del processo, e la sola differenza è che i
permessi ordinari da esse risultanti vengono automaticamente rimappati anche
su una ACL di accesso assegnata automaticamente al nuovo file, che contiene
soltanto le tre corrispondenti voci di tipo \const{ACL\_USER\_OBJ},
\const{ACL\_GROUP\_OBJ} e \const{ACL\_OTHER}.

Se invece è presente una ACL di default sulla directory che contiene il nuovo
file questa diventerà automaticamente la sua ACL di accesso, a meno di non
aver indicato, nelle funzioni di creazione che lo consentono, uno specifico
valore per i permessi ordinari;\footnote{tutte le funzioni citate in
  precedenza supportano un argomento \var{mode} che indichi un insieme di
  permessi iniziale.} in tal caso saranno eliminati dalle voci corrispondenti
nella ACL tutti quelli non presenti in tale indicazione.

Dato che questa è la ragione che ha portato alla loro creazione, la principale
modifica introdotta con la presenza della ACL è quella alle regole del
controllo di accesso ai file illustrate in sez.~\ref{sec:file_perm_overview}.
Come nel caso ordinario per il controllo vengono sempre utilizzati gli
identificatori del gruppo \textit{effective} del processo, ma in presenza di
ACL i passi attraverso i quali viene stabilito se esso ha diritto di accesso
sono i seguenti:
\begin{enumerate*}
\item Se l'\ids{UID} del processo è nullo l'accesso è sempre garantito senza
  nessun controllo.
\item Se l'\ids{UID} del processo corrisponde al proprietario del file allora:
  \begin{itemize*}
  \item se la voce \const{ACL\_USER\_OBJ} contiene il permesso richiesto,
    l'accesso è consentito;
  \item altrimenti l'accesso è negato.
  \end{itemize*}
\item Se l'\ids{UID} del processo corrisponde ad un qualunque qualificatore
  presente in una voce \const{ACL\_USER} allora:
  \begin{itemize*}
  \item se la voce \const{ACL\_USER} corrispondente e la voce
    \const{ACL\_MASK} contengono entrambe il permesso richiesto, l'accesso è
    consentito;
  \item altrimenti l'accesso è negato.
  \end{itemize*}
\item Se è il \ids{GID} del processo o uno dei \ids{GID} supplementari
  corrisponde al gruppo proprietario del file allora: 
  \begin{itemize*}
  \item se la voce \const{ACL\_GROUP\_OBJ} e una eventuale voce
    \const{ACL\_MASK} (se non vi sono voci di tipo \const{ACL\_GROUP} questa
    può non essere presente) contengono entrambe il permesso richiesto,
    l'accesso è consentito;
  \item altrimenti l'accesso è negato.
  \end{itemize*}
\item Se è il \ids{GID} del processo o uno dei \ids{GID} supplementari
  corrisponde ad un qualunque qualificatore presente in una voce
  \const{ACL\_GROUP} allora:
  \begin{itemize*}
  \item se la voce \const{ACL\_GROUP} corrispondente e la voce
    \const{ACL\_MASK} contengono entrambe il permesso richiesto, l'accesso è
    consentito;
  \item altrimenti l'accesso è negato.
  \end{itemize*}
\item Se la voce \const{ACL\_USER\_OBJ} contiene il permesso richiesto,
  l'accesso è consentito, altrimenti l'accesso è negato.
\end{enumerate*}

I passi di controllo vengono eseguiti esattamente in questa sequenza, e la
decisione viene presa non appena viene trovata una corrispondenza con gli
identificatori del processo. Questo significa che i permessi presenti in una
voce di tipo \const{ACL\_USER} hanno la precedenza sui permessi ordinari
associati al gruppo proprietario del file (vale a dire su
\const{ACL\_GROUP\_OBJ}).

Per la gestione delle ACL lo standard \textit{POSIX 1003.1e Draft 17} ha
previsto delle apposite funzioni ed tutta una serie di tipi di dati
dedicati;\footnote{fino a definire un tipo di dato e delle costanti apposite
  per identificare i permessi standard di lettura, scrittura ed esecuzione.}
tutte le operazioni devono essere effettuate attraverso tramite questi tipi di
dati, che incapsulano tutte le informazioni contenute nelle ACL. La prima di
queste funzioni che prendiamo in esame è \funcd{acl\_init}, il cui prototipo
è:
\begin{functions}
  \headdecl{sys/types.h} 
  \headdecl{sys/acl.h}
  
  \funcdecl{acl\_t acl\_init(int count)}

  Inizializza un'area di lavoro per una ACL di \param{count} voci.
  
  \bodydesc{La funzione restituisce un puntatore all'area di lavoro in caso di
    successo e \val{NULL} in caso di errore, nel qual caso \var{errno}
    assumerà uno dei valori:
  \begin{errlist}
  \item[\errcode{EINVAL}] il valore di \param{count} è negativo.
  \item[\errcode{ENOMEM}] non c'è sufficiente memoria disponibile.
  \end{errlist}
}
\end{functions}

La funzione alloca ed inizializza un'area di memoria che verrà usata per
mantenere i dati di una ACL contenente fino ad un massimo di \param{count}
voci. La funzione ritorna un valore di tipo \type{acl\_t}, da usare in tutte
le altre funzioni che operano sulla ACL. La funzione si limita alla
allocazione iniziale e non inserisce nessun valore nella ACL che resta vuota.
Si tenga presente che pur essendo \type{acl\_t} un \index{tipo!opaco} tipo
opaco che identifica ``\textsl{l'oggetto}'' ACL, il valore restituito dalla
funzione non è altro che un puntatore all'area di memoria allocata per i dati
richiesti; pertanto in caso di fallimento verrà restituito un puntatore nullo
e si dovrà confrontare il valore di ritorno della funzione con
``\code{(acl\_t) NULL}''.

Una volta che si siano completate le operazioni sui dati di una ACL la memoria
allocata dovrà essere liberata esplicitamente attraverso una chiamata alla
funzione \funcd{acl\_free}, il cui prototipo è:
\begin{functions}
  \headdecl{sys/types.h} 
  \headdecl{sys/acl.h}
  
  \funcdecl{int acl\_free(void * obj\_p)}

  Disalloca la memoria riservata per i dati di una ACL.
  
  \bodydesc{La funzione restituisce 0 in caso di successo e $-1$ se
    \param{obj\_p} non è un puntatore valido, nel qual caso \var{errno}
    assumerà il valore \errcode{EINVAL} 
}
\end{functions}

Si noti come la funzione richieda come argomento un puntatore di tipo
``\ctyp{void *}'', essa infatti può essere usata non solo per liberare la
memoria allocata per i dati di una ACL, ma anche per quella usata per creare
le stringhe di descrizione testuale delle ACL o per ottenere i valori dei
qualificatori di una voce; pertanto a seconda dei casi occorrerà eseguire un
\textit{cast} a ``\ctyp{void *}'' del tipo di dato di cui si vuole eseguire la
disallocazione.  Si tenga presente poi che oltre a \func{acl\_init} esistono
molte altre funzioni che possono allocare memoria per i dati delle ACL, è
pertanto opportuno tenere traccia di tutte queste funzioni perché alla fine
delle operazioni tutta la memoria allocata dovrà essere liberata con
\func{acl\_free}.

Una volta che si abbiano a disposizione i dati di una ACL tramite il
riferimento ad oggetto di tipo \type{acl\_t} questi potranno essere copiati
con la funzione \funcd{acl\_dup}, il cui prototipo è:
\begin{functions}
  \headdecl{sys/types.h} 
  \headdecl{sys/acl.h}
  
  \funcdecl{acl\_t acl\_dup(acl\_t acl)}

  Crea una copia della ACL \param{acl}.
  
  \bodydesc{La funzione restituisce un oggetto di tipo \type{acl\_t} in caso
    di successo e \code{(acl\_t)NULL} in caso di errore, nel qual caso
    \var{errno} assumerà uno dei valori:
  \begin{errlist}
  \item[\errcode{EINVAL}] l'argomento \param{acl} non è un puntatore valido
    per una ACL.
  \item[\errcode{ENOMEM}] non c'è sufficiente memoria disponibile per eseguire
    la copia.
  \end{errlist}
}
\end{functions}

La funzione crea una copia dei dati della ACL indicata tramite l'argomento
\param{acl}, allocando autonomamente tutto spazio necessario alla copia e
restituendo un secondo oggetto di tipo \type{acl\_t} come riferimento a
quest'ultima.  Valgono per questo le stesse considerazioni fatte per il valore
di ritorno di \func{acl\_init}, ed in particolare il fatto che occorrerà
prevedere una ulteriore chiamata esplicita a \func{acl\_free} per liberare la
memoria occupata dalla copia.

Se si deve creare una ACL manualmente l'uso di \func{acl\_init} è scomodo,
dato che la funzione restituisce una ACL vuota, una alternativa allora è usare
\funcd{acl\_from\_mode} che consente di creare una ACL a partire da un valore
di permessi ordinari, il prototipo della funzione è:
\begin{functions}
  \headdecl{sys/types.h} 
  \headdecl{sys/acl.h}
  
  \funcdecl{acl\_t acl\_from\_mode(mode\_t mode)}

  Crea una ACL inizializzata con i permessi di \param{mode}.
  
  \bodydesc{La funzione restituisce un oggetto di tipo \type{acl\_t} in caso
    di successo e \code{(acl\_t)NULL} in caso di errore, nel qual caso
    \var{errno} assumerà il valore \errval{ENOMEM}.

}
\end{functions}

La funzione restituisce una ACL inizializzata con le tre voci obbligatorie
\const{ACL\_USER\_OBJ}, \const{ACL\_GROUP\_OBJ} e \const{ACL\_OTHER} già
impostate secondo la corrispondenza ai valori dei permessi ordinari indicati
dalla maschera passata nell'argomento \param{mode}. Questa funzione è una
estensione usata dalle ACL di Linux e non è portabile, ma consente di
semplificare l'inizializzazione in maniera molto comoda. 

Altre due funzioni che consentono di creare una ACL già inizializzata sono
\funcd{acl\_get\_fd} e \funcd{acl\_get\_file}, che però sono per lo più
utilizzate per leggere la ACL corrente di un file; i rispettivi prototipi
sono:
\begin{functions}
  \headdecl{sys/types.h} 
  \headdecl{sys/acl.h}
  
  \funcdecl{acl\_t acl\_get\_file(const char *path\_p, acl\_type\_t type)}
  \funcdecl{acl\_t acl\_get\_fd(int fd)}

  Ottiene i dati delle ACL di un file.
  
  \bodydesc{La funzione restituisce un oggetto di tipo \type{acl\_t} in caso
    di successo e \code{(acl\_t)NULL} in caso di errore, nel qual caso
    \var{errno} assumerà uno dei valori:
  \begin{errlist}
  \item[\errcode{ENOMEM}] non c'è memoria sufficiente per allocare i dati.
  \item[\errcode{ENOTSUP}] il filesystem cui fa riferimento il file non
    supporta le ACL.
  \end{errlist}
  ed inoltre \errval{EBADF} per \func{acl\_get\_fd}, ed \errval{EINVAL} per
  valori scorretti di \param{type} e tutti i possibili errori per l'accesso ad
  un file per \func{acl\_get\_file}.

}
\end{functions}

Le due funzioni ritornano, con un oggetto di tipo \type{acl\_t}, il valore
della ACL correntemente associata ad un file, che può essere identificato
tramite un file descriptor usando \func{acl\_get\_fd} o con un
\textit{pathname} usando \func{acl\_get\_file}. Nel caso di quest'ultima
funzione, che può richiedere anche la ACL relativa ad una directory, il
secondo argomento \param{type} consente di specificare se si vuole ottenere la
ACL di default o quella di accesso. Questo argomento deve essere di tipo
\type{acl\_type\_t} e può assumere solo i due valori riportati in
tab.~\ref{tab:acl_type}.

\begin{table}[htb]
  \centering
  \footnotesize
  \begin{tabular}{|l|l|}
    \hline
    \textbf{Tipo} & \textbf{Descrizione} \\
    \hline
    \hline
    \const{ACL\_TYPE\_ACCESS} & indica una ACL di accesso.\\
    \const{ACL\_TYPE\_DEFAULT}& indica una ACL di default.\\  
    \hline
  \end{tabular}
  \caption{Le costanti che identificano il tipo di ACL.}
  \label{tab:acl_type}
\end{table}

Si tenga presente che nel caso di \func{acl\_get\_file} occorrerà che il
processo chiamante abbia privilegi di accesso sufficienti a poter leggere gli
attributi estesi dei file (come illustrati in sez.~\ref{sec:file_xattr});
inoltre una ACL di tipo \const{ACL\_TYPE\_DEFAULT} potrà essere richiesta
soltanto per una directory, e verrà restituita solo se presente, altrimenti
verrà restituita una ACL vuota.

Infine si potrà creare una ACL direttamente dalla sua rappresentazione
testuale con la funzione  \funcd{acl\_from\_text}, il cui prototipo è:
\begin{functions}
  \headdecl{sys/types.h} 
  \headdecl{sys/acl.h}
  
  \funcdecl{acl\_t acl\_from\_text(const char *buf\_p)}

  Crea una ACL a partire dalla sua rappresentazione testuale.
  
  \bodydesc{La funzione restituisce un oggetto di tipo \type{acl\_t} in caso
    di successo e \code{(acl\_t)NULL} in caso di errore, nel qual caso
    \var{errno} assumerà uno dei valori:
  \begin{errlist}
  \item[\errcode{ENOMEM}] non c'è memoria sufficiente per allocare i dati.
  \item[\errcode{EINVAL}] la rappresentazione testuale all'indirizzo
    \param{buf\_p} non è valida.
  \end{errlist}

}
\end{functions}

La funzione prende come argomento il puntatore ad un buffer dove si è inserita
la rappresentazione testuale della ACL che si vuole creare, la memoria
necessaria viene automaticamente allocata ed in caso di successo viene
restituito come valore di ritorno un oggetto di tipo \type{acl\_t} con il
contenuto della stessa, che come per le precedenti funzioni, dovrà essere
disallocato esplicitamente al termine del suo utilizzo.

La rappresentazione testuale di una ACL è quella usata anche dai comandi
ordinari per la gestione delle ACL (\texttt{getfacl} e \texttt{setfacl}), che
prevede due diverse forme, estesa e breve, entrambe supportate da
\func{acl\_from\_text}. La forma estesa prevede che sia specificata una voce
per riga, nella forma:
\begin{Verbatim}
  tipo:qualificatore:permessi
\end{Verbatim}
dove il tipo può essere uno fra \texttt{user}, \texttt{group}, \texttt{other}
e \texttt{mask}. Il qualificatore è presente solo per \texttt{user} e
\texttt{group} e indica l'utente o il gruppo a cui la voce si riferisce; i
permessi sono espressi con una tripletta di lettere analoga a quella usata per
i permessi dei file.\footnote{vale a dire \texttt{r} per il permesso di
  lettura, \texttt{w} per il permesso di scrittura, \texttt{x} per il permesso
  di esecuzione (scritti in quest'ordine) e \texttt{-} per l'assenza del
  permesso.}

Va precisato che i due tipi \texttt{user} e \texttt{group} sono usati
rispettivamente per indicare delle voci relative ad utenti e
gruppi,\footnote{cioè per voci di tipo \const{ACL\_USER\_OBJ} e
  \const{ACL\_USER} per \texttt{user} e \const{ACL\_GROUP\_OBJ} e
  \const{ACL\_GROUP} per \texttt{group}.} applicate sia a quelli proprietari
del file che a quelli generici; quelle dei proprietari si riconoscono per
l'assenza di un qualificatore, ed in genere si scrivono per prima delle altre.
Il significato delle voci di tipo \texttt{mask} e \texttt{mark} è evidente. In
questa forma si possono anche inserire dei commenti precedendoli con il
carattere ``\texttt{\#}''.

La forma breve prevede invece la scrittura delle singole voci su una riga,
separate da virgole; come specificatori del tipo di voce si possono usare le
iniziali dei valori usati nella forma estesa (cioè ``\texttt{u}'',
``\texttt{g}'', ``\texttt{o}'' e ``\texttt{m}''), mentre le altri parte della
voce sono le stesse. In questo caso non sono consentiti permessi.

Per la conversione inversa, che consente di ottenere la rappresentazione
testuale di una ACL, sono invece disponibili due funzioni, la prima delle due,
di uso più immediato, è \funcd{acl\_to\_text}, il cui prototipo è:
\begin{functions}
  \headdecl{sys/types.h} 
  \headdecl{sys/acl.h}
  
  \funcdecl{char * acl\_to\_text(acl\_t acl, ssize\_t *len\_p)}

  Produce la rappresentazione testuale di una ACL.
  
  \bodydesc{La funzione restituisce il puntatore ad una stringa con la
    rappresentazione testuale della ACL in caso di successo e
    \code(acl\_t){NULL} in caso di errore, nel qual caso \var{errno} assumerà
    uno dei valori:
  \begin{errlist}
  \item[\errcode{ENOMEM}] non c'è memoria sufficiente per allocare i dati.
  \item[\errcode{EINVAL}] la ACL indicata da \param{acl} non è valida.
  \end{errlist}

}
\end{functions}

La funzione restituisce il puntatore ad una stringa terminata da NUL
contenente la rappresentazione in forma estesa della ACL passata come
argomento, ed alloca automaticamente la memoria necessaria. Questa dovrà poi
essere liberata, quando non più necessaria, con \func{acl\_free}. Se
nell'argomento \param{len\_p} si passa un valore puntatore ad una variabile
intera in questa verrà restituita la dimensione della stringa con la
rappresentazione testuale (non comprendente il carattere nullo finale). 

La seconda funzione, \funcd{acl\_to\_any\_text}, permette di controllare con
dovizia di dettagli la generazione della stringa contenente la
rappresentazione testuale della ACL, il suo prototipo è:
\begin{functions}
  \headdecl{sys/types.h} 
  \headdecl{sys/acl.h}
  
  \funcdecl{char * acl\_to\_any\_text(acl\_t acl, const char *prefix, char
    separator, int options)}

  Produce la rappresentazione testuale di una ACL.

  \bodydesc{La funzione restituisce il puntatore ad una stringa con la
    rappresentazione testuale della ACL in caso di successo e \val{NULL} in
    caso di errore, nel qual caso \var{errno} assumerà uno dei valori:
  \begin{errlist}
  \item[\errcode{ENOMEM}] non c'è memoria sufficiente per allocare i dati.
  \item[\errcode{EINVAL}] la ACL indicata da \param{acl} non è valida.
  \end{errlist}

}
\end{functions}

La funzione converte in formato testo la ACL indicata dall'argomento
\param{acl}, usando il carattere \param{separator} come separatore delle
singole voci; se l'argomento \param{prefix} non è nullo la stringa da esso
indicata viene utilizzata come prefisso per le singole voci. 

L'ultimo argomento, \param{options}, consente di controllare la modalità con
cui viene generata la rappresentazione testuale. Un valore nullo fa si che
vengano usati gli identificatori standard \texttt{user}, \texttt{group},
\texttt{other} e \texttt{mask} con i nomi di utenti e gruppi risolti rispetto
ai loro valori numerici. Altrimenti si può specificare un valore in forma di
maschera binaria, da ottenere con un OR aritmetico dei valori riportati in
tab.~\ref{tab:acl_to_text_options}.

\begin{table}[htb]
  \centering
  \footnotesize
  \begin{tabular}{|l|p{8cm}|}
    \hline
    \textbf{Tipo} & \textbf{Descrizione} \\
    \hline
    \hline
    \const{TEXT\_ABBREVIATE}     & stampa le voci in forma abbreviata.\\
    \const{TEXT\_NUMERIC\_IDS}   & non effettua la risoluzione numerica di
                                   \ids{UID} e \ids{GID}.\\
    \const{TEXT\_SOME\_EFFECTIVE}& per ciascuna voce che contiene permessi che
                                   vengono eliminati dalla \const{ACL\_MASK}
                                   viene generato un commento con i permessi 
                                   effettivamente risultanti; il commento è
                                   separato con un tabulatore.\\
    \const{TEXT\_ALL\_EFFECTIVE} & viene generato un commento con i permessi
                                   effettivi per ciascuna voce che contiene
                                   permessi citati nella \const{ACL\_MASK},
                                   anche quando questi non vengono modificati
                                   da essa; il commento è separato con un
                                   tabulatore.\\
    \const{TEXT\_SMART\_INDENT}  & da usare in combinazione con le precedenti
                                   \const{TEXT\_SOME\_EFFECTIVE} e
                                   \const{TEXT\_ALL\_EFFECTIVE} aumenta
                                   automaticamente il numero di spaziatori
                                   prima degli eventuali commenti in modo da
                                   mantenerli allineati.\\
    \hline
  \end{tabular}
  \caption{Possibili valori per l'argomento \param{options} di
    \func{acl\_to\_any\_text}.} 
  \label{tab:acl_to_text_options}
\end{table}

Come per \func{acl\_to\_text} anche in questo caso il buffer contenente la
rappresentazione testuale dell'ACL, di cui la funzione restituisce
l'indirizzo, viene allocato automaticamente, e dovrà essere esplicitamente
disallocato con una chiamata ad \func{acl\_free}. Si tenga presente infine che
questa funzione è una estensione specifica di Linux, e non è presente nella
bozza dello standard POSIX.1e.

Per quanto utile per la visualizzazione o l'impostazione da comando delle ACL,
la forma testuale non è la più efficiente per poter memorizzare i dati
relativi ad una ACL, ad esempio quando si vuole eseguirne una copia a scopo di
archiviazione. Per questo è stata prevista la possibilità di utilizzare una
rappresentazione delle ACL in una apposita forma binaria contigua e
persistente. È così possibile copiare il valore di una ACL in un buffer e da
questa rappresentazione tornare indietro e generare una ACL. 

Lo standard POSIX.1e prevede a tale scopo tre funzioni, la prima e più
semplice è \funcd{acl\_size}, che consente di ottenere la dimensione che avrà
la citata rappresentazione binaria, in modo da poter allocare per essa un
buffer di dimensione sufficiente, il suo prototipo è:
\begin{functions}
  \headdecl{sys/types.h} 
  \headdecl{sys/acl.h}
  
  \funcdecl{ssize\_t acl\_size(acl\_t acl)}

  Determina la dimensione della rappresentazione binaria di una ACL.

  \bodydesc{La funzione restituisce in caso di successo la dimensione in byte
    della rappresentazione binaria della ACL indicata da \param{acl} e $-1$ in
    caso di errore, nel qual caso \var{errno} assumerà uno dei valori:
  \begin{errlist}
  \item[\errcode{EINVAL}] la ACL indicata da \param{acl} non è valida.
  \end{errlist}

}
\end{functions}

Prima di effettuare la lettura della rappresentazione binaria è sempre
necessario allocare un buffer di dimensione sufficiente a contenerla, pertanto
prima si dovrà far ricorso a \funcd{acl\_size} per ottenere tale dimensione e
poi allocare il buffer con una delle funzioni di
sez.~\ref{sec:proc_mem_alloc}. Una volta terminato l'uso della
rappresentazione binaria, il buffer dovrà essere esplicitamente disallocato.

La funzione che consente di leggere la rappresentazione binaria di una ACL è
\funcd{acl\_copy\_ext}, il cui prototipo è:
\begin{functions}
  \headdecl{sys/types.h} 
  \headdecl{sys/acl.h}
  
  \funcdecl{ssize\_t acl\_copy\_ext(void *buf\_p, acl\_t acl, ssize\_t size)}

  Ottiene la rappresentazione binaria di una ACL.

  \bodydesc{La funzione restituisce in caso di successo la dimensione in byte
    della rappresentazione binaria della ACL indicata da \param{acl} e $-1$ in
    caso di errore, nel qual caso \var{errno} assumerà uno dei valori:
  \begin{errlist}
  \item[\errcode{EINVAL}] la ACL indicata da \param{acl} non è valida o
    \param{size} è negativo o nullo.
  \item[\errcode{ERANGE}] il valore di \param{size} è più piccolo della
    dimensione della rappresentazione della ACL.
  \end{errlist}

}
\end{functions}

La funzione salverà la rappresentazione binaria della ACL indicata da
\param{acl} sul buffer posto all'indirizzo \param{buf\_p} e lungo \param{size}
byte, restituendo la dimensione della stessa come valore di ritorno. Qualora
la dimensione della rappresentazione ecceda il valore di \param{size} la
funzione fallirà con un errore di \errcode{ERANGE}. La funzione non ha nessun
effetto sulla ACL indicata da \param{acl}.

Viceversa se si vuole ripristinare una ACL a partire dalla rappresentazione
binaria della stessa disponibile in un buffer si potrà usare la funzione 
\funcd{acl\_copy\_int}, il cui prototipo è:
\begin{functions}
  \headdecl{sys/types.h} 
  \headdecl{sys/acl.h}
  
  \funcdecl{ssize\_t acl\_copy\_int(const void *buf\_p)}

  Ripristina la rappresentazione binaria di una ACL.

  \bodydesc{La funzione restituisce un oggetto di tipo \type{acl\_t} in caso
    di successo e \code{(acl\_t)NULL} in caso di errore, nel qual caso
    \var{errno} assumerà uno dei valori:
  \begin{errlist}
  \item[\errcode{EINVAL}] il buffer all'indirizzo \param{buf\_p} non contiene
    una rappresentazione corretta di una ACL.
  \item[\errcode{ENOMEM}] non c'è memoria sufficiente per allocare un oggetto
    \type{acl\_t} per la ACL richiesta.
  \end{errlist}

}
\end{functions}

La funzione in caso di successo alloca autonomamente un oggetto di tipo
\type{acl\_t} che viene restituito come valore di ritorno con il contenuto
della ACL rappresentata dai dati contenuti nel buffer puntato da
\param{buf\_p}. Si ricordi che come per le precedenti funzioni l'oggetto
\type{acl\_t} dovrà essere disallocato esplicitamente al termine del suo
utilizzo.

Una volta che si disponga della ACL desiderata, questa potrà essere impostata
su un file o una directory. Per impostare una ACL sono disponibili due
funzioni; la prima è \funcd{acl\_set\_file}, che opera sia su file che su
directory, ed il cui prototipo è:
\begin{functions}
  \headdecl{sys/types.h} 
  \headdecl{sys/acl.h}
  
  \funcdecl{int acl\_set\_file(const char *path, acl\_type\_t type, acl\_t
    acl)}

  Imposta una ACL su un file o una directory.

  \bodydesc{La funzione restituisce $0$ in caso di successo e $-1$ in caso di
    errore, nel qual caso \var{errno} assumerà uno dei valori:
  \begin{errlist}
  \item[\errcode{EACCES}] o un generico errore di accesso a \param{path} o il
    valore di \param{type} specifica una ACL il cui tipo non può essere
    assegnato a \param{path}.
  \item[\errcode{EINVAL}] o \param{acl} non è una ACL valida, o \param{type}
    ha in valore non corretto.
  \item[\errcode{ENOSPC}] non c'è spazio disco sufficiente per contenere i
    dati aggiuntivi della ACL.
  \item[\errcode{ENOTSUP}] si è cercato di impostare una ACL su un file
    contenuto in un filesystem che non supporta le ACL.
  \end{errlist}
  ed inoltre \errval{ENOENT}, \errval{ENOTDIR}, \errval{ENAMETOOLONG},
  \errval{EROFS}, \errval{EPERM}.
}
\end{functions}

La funzione consente di assegnare la ACL contenuta in \param{acl} al file o
alla directory indicate dal \textit{pathname} \param{path}, mentre
con \param{type} si indica il tipo di ACL utilizzando le costanti di
tab.~\ref{tab:acl_type}, ma si tenga presente che le ACL di default possono
essere solo impostate qualora \param{path} indichi una directory. Inoltre
perché la funzione abbia successo la ACL dovrà essere valida, e contenere
tutti le voci necessarie, unica eccezione è quella in cui si specifica una ACL
vuota per cancellare la ACL di default associata a
\param{path}.\footnote{questo però è una estensione della implementazione delle
  ACL di Linux, la bozza di standard POSIX.1e prevedeva l'uso della apposita
  funzione \funcd{acl\_delete\_def\_file}, che prende come unico argomento il
  \textit{pathname} della directory di cui si vuole cancellare l'ACL di
  default, per i dettagli si ricorra alla pagina di manuale.}  La seconda
funzione che consente di impostare una ACL è \funcd{acl\_set\_fd}, ed il suo
prototipo è:
\begin{functions}
  \headdecl{sys/types.h} 
  \headdecl{sys/acl.h}
  
  \funcdecl{int acl\_set\_fd(int fd, acl\_t acl)}

  Imposta una ACL su un file descriptor.

  \bodydesc{La funzione restituisce $0$ in caso di successo e $-1$ in caso di
    errore, nel qual caso \var{errno} assumerà uno dei valori:
  \begin{errlist}
  \item[\errcode{EINVAL}] o \param{acl} non è una ACL valida, o \param{type}
    ha in valore non corretto.
  \item[\errcode{ENOSPC}] non c'è spazio disco sufficiente per contenere i
    dati aggiuntivi della ACL.
  \item[\errcode{ENOTSUP}] si è cercato di impostare una ACL su un file
    contenuto in un filesystem che non supporta le ACL.
  \end{errlist}
  ed inoltre \errval{EBADF}, \errval{EROFS}, \errval{EPERM}.
}
\end{functions}

La funzione è del tutto è analoga a \funcd{acl\_set\_file} ma opera
esclusivamente sui file identificati tramite un file descriptor. Non dovendo
avere a che fare con directory (e con la conseguente possibilità di avere una
ACL di default) la funzione non necessita che si specifichi il tipo di ACL,
che sarà sempre di accesso, e prende come unico argomento, a parte il file
descriptor, la ACL da impostare.

Le funzioni viste finora operano a livello di una intera ACL, eseguendo in una
sola volta tutte le operazioni relative a tutte le voci in essa contenuta. In
generale è possibile modificare un singolo valore all'interno di una singola
voce direttamente con le funzioni previste dallo standard POSIX.1e.  Queste
funzioni però sono alquanto macchinose da utilizzare per cui è molto più
semplice operare direttamente sulla rappresentazione testuale. Questo è il
motivo per non tratteremo nei dettagli dette funzioni, fornendone solo una
descrizione sommaria; chi fosse interessato potrà ricorrere alle pagina di
manuale.

Se si vuole operare direttamente sui contenuti di un oggetto di tipo
\type{acl\_t} infatti occorre fare riferimento alle singole voci tramite gli
opportuni puntatori di tipo \type{acl\_entry\_t}, che possono essere ottenuti
dalla funzione \funcd{acl\_get\_entry} (per una voce esistente) o dalla
funzione \funcd{acl\_create\_entry} per una voce da aggiungere. Nel caso della
prima funzione si potrà poi ripetere la lettura per ottenere i puntatori alle
singole voci successive alla prima.

Una volta ottenuti detti puntatori si potrà operare sui contenuti delle singole
voci; con le funzioni \funcd{acl\_get\_tag\_type}, \funcd{acl\_get\_qualifier},
\funcd{acl\_get\_permset} si potranno leggere rispettivamente tipo,
qualificatore e permessi mentre con le corrispondente funzioni
\funcd{acl\_set\_tag\_type}, \funcd{acl\_set\_qualifier},
\funcd{acl\_set\_permset} si possono impostare i valori; in entrambi i casi
vengono utilizzati tipi di dato ad hoc.\footnote{descritti nelle singole
  pagine di manuale.} Si possono poi copiare i valori di una voce da una ACL
ad un altra con \funcd{acl\_copy\_entry} o eliminare una voce da una ACL con
\funcd{acl\_delete\_entry}.

\itindend{Access~Control~List~(ACL)}


\subsection{La gestione delle quote disco}
\label{sec:disk_quota}

Quella delle quote disco è una funzionalità introdotta inizialmente da BSD, e
presente in Linux fino dai kernel dalla serie 2.0, che consente di porre dei
tetti massimi al consumo delle risorse di un filesystem (spazio disco e
\itindex{inode} \textit{inode}) da parte di utenti e gruppi. Dato che la
funzionalità ha senso solo per i filesystem su cui si mantengono i dati degli
utenti\footnote{in genere la si attiva sul filesystem che contiene le
  \textit{home} degli utenti, dato che non avrebbe senso per i file di sistema
  che in genere appartengono all'amministratore.} essa deve essere
esplicitamente richiesta; questo si fa tramite due distinte opzioni di
montaggio, \texttt{usrquota} e \texttt{grpquota} che abilitano le quote
rispettivamente per gli utenti e per i gruppi. Grazie a questo è possibile
usare le limitazioni sulle quote solo sugli utenti o solo sui gruppi.

Il meccanismo prevede che per ciascun filesystem che supporta le quote disco
(i vari \textit{extN}, \textit{btrfs}, \textit{XFS}, \textit{JFS},
\textit{ReiserFS}) il kernel provveda sia a mantenere aggiornati i dati
relativi al consumo delle risorse da parte di utenti e/o gruppi che a far
rispettare i limiti imposti dal sistema, con la generazione di un errore di
\errval{EDQUOT} per tutte le operazioni sui file che porterebbero ad un
superamento degli stessi. Si tenga presente che questi due compiti sono
separati, il primo si attiva al montaggio del filesystem con le quote
attivate, il secondo deve essere abilitato esplicitamente.

Per il mantenimento dei dati di consumo delle risorse vengono usati due file
riservati (uno per le quote utente e l'altro per le quote gruppo) nella
directory radice del filesystem su cui si sono attivate le quote;\footnote{la
  cosa vale per tutti i filesystem tranne \textit{XFS} che mantiene i dati
  internamente.} con la versione 2 del supporto delle quote, l'unica rimasta
in uso, questi file sono \texttt{aquota.user} e \texttt{aquota.group}, in
precedenza erano \texttt{quota.user} e \texttt{quota.group}. Dato che i file
vengono aggiornati soltanto se il filesystem è stato montato con il supporto
delle quote, se si abilita questo in un secondo tempo (o se si eseguono
operazioni sul filesystem senza averlo abilitato) i dati contenuti possono non
corrispondere esattamente allo stato corrente del consumo delle risorse; per
questo in genere prima di montare in scrittura un filesystem su cui sono
abilitate le quote in genere viene utilizzato il comando \cmd{quotacheck} per
verificare e aggiornare i dati.

Le restrizioni sul consumo delle risorse prevedono due limiti, il primo viene
detto \textit{soft limit} e può essere superato per brevi periodi di tempo, il
secondo viene detto \textit{hard limit} non può mai essere superato. Il
periodo di tempo per cui è possibile superare il \textit{soft limit} è detto
``\textsl{periodo di grazia}'' (\textit{grace period}), passato questo tempo
il passaggio del \textit{soft limit} viene trattato allo stesso modo
dell'\textit{hard limit}.  Questi limiti riguardano separatamente sia lo
spazio disco (i blocchi) che il numero di file (gli \itindex{inode}
\textit{inode}) e devono pertanto essere specificati per entrambe le risorse.

La funzione che consente di controllare tutti i vari aspetti della gestione
delle quote è \funcd{quotactl}, ed il suo prototipo è:
\begin{functions}
  \headdecl{sys/types.h} 
  \headdecl{sys/quota.h}
  
  \funcdecl{quotactl(int cmd, const char *dev, int id, caddr\_t addr)}

  Esegue una operazione di controllo sulle quote disco.

  \bodydesc{La funzione restituisce $0$ in caso di successo e $-1$ in caso di
    errore, nel qual caso \var{errno} assumerà uno dei valori:
  \begin{errlist}
  \item[\errcode{EACCES}] il file delle quote non è un file ordinario.
  \item[\errcode{EBUSY}] si è richiesto \const{Q\_QUOTAON} ma le quote sono
    già attive.
  \item[\errcode{EFAULT}] l'indirizzo \param{addr} non è valido.
  \item[\errcode{EIO}] errore di lettura/scrittura sul file delle quote.
  \item[\errcode{EMFILE}] non si può aprire il file delle quote avendo
    superato il limite sul numero di file aperti nel sistema. 
  \item[\errcode{EINVAL}] o \param{cmd} non è un comando valido,
    o il dispositivo \param{dev} non esiste.
  \item[\errcode{ENODEV}] \param{dev} non corrisponde ad un \textit{mount
      point} attivo.
  \item[\errcode{ENOPKG}] il kernel è stato compilato senza supporto per le
    quote. 
  \item[\errcode{ENOTBLK}] \param{dev} non è un dispositivo a blocchi.
  \item[\errcode{EPERM}] non si hanno i permessi per l'operazione richiesta.
  \item[\errcode{ESRCH}] è stato richiesto uno fra \const{Q\_GETQUOTA},
    \const{Q\_SETQUOTA}, \const{Q\_SETUSE}, \const{Q\_SETQLIM} per un
    filesystem senza quote attivate.
  \end{errlist}
}
\end{functions}

La funzione richiede che il filesystem sul quale si vuole operare sia montato
con il supporto delle quote abilitato; esso deve essere specificato con il
nome del file di dispositivo nell'argomento \param{dev}. Per le operazioni che
lo richiedono inoltre si dovrà indicare con l'argomento \param{id} l'utente o
il gruppo (specificati rispettivamente per \ids{UID} e \ids{GID}) su cui si
vuole operare. Alcune operazioni usano l'argomento \param{addr} per indicare
un indirizzo ad un area di memoria il cui utilizzo dipende dall'operazione
stessa.

Il tipo di operazione che si intende effettuare deve essere indicato tramite
il primo argomento \param{cmd}, questo in genere viene specificato con
l'ausilio della macro \macro{QCMD}:
\begin{functions}
  \funcdecl{int QCMD(subcmd,type)} Imposta il comando \param{subcmd} per il
  tipo di quote (utente o gruppo) \param{type}.
\end{functions}
\noindent che consente di specificare, oltre al tipo di operazione, se questa
deve applicarsi alle quote utente o alle quote gruppo, nel qual
caso \param{type} deve essere rispettivamente \const{USRQUOTA} o
\const{GRPQUOTA}.


\begin{table}[htb]
  \centering
  \footnotesize
  \begin{tabular}{|l|p{10cm}|}
    \hline
    \textbf{Comando} & \textbf{Descrizione} \\
    \hline
    \hline
    \const{Q\_QUOTAON}  & Attiva l'applicazione delle quote disco per il
                          filesystem indicato da \param{dev}, si deve passare
                          in \param{addr} il \textit{pathname} al file che
                          mantiene le quote, che deve esistere, e \param{id}
                          deve indicare la versione del formato con uno dei
                          valori di tab.~\ref{tab:quotactl_id_format};
                          l'operazione richiede i privilegi di
                          amministratore.\\
    \const{Q\_QUOTAOFF} & Disattiva l'applicazione delle quote disco per il
                          filesystem indicato da \param{dev}, \param{id}
                          e \param{addr} vengono ignorati; l'operazione
                          richiede i privilegi di amministratore.\\  
    \const{Q\_GETQUOTA} & Legge i limiti ed i valori correnti delle quote nel
                          filesystem indicato da \param{dev} per l'utente o
                          il gruppo specificato da \param{id}; si devono avere
                          i privilegi di amministratore per leggere i dati
                          relativi ad altri utenti o a gruppi di cui non si fa
                          parte, il risultato viene restituito in una struttura
                          \struct{dqblk} all'indirizzo indicato
                          da \param{addr}.\\
    \const{Q\_SETQUOTA} & Imposta i limiti per le quote nel filesystem
                          indicato da \param{dev} per l'utente o il gruppo
                          specificato da \param{id} secondo i valori ottenuti
                          dalla struttura \struct{dqblk} puntata
                          da \param{addr}; l'operazione richiede i privilegi
                          di amministratore.\\ 
    \const{Q\_GETINFO}  & Legge le informazioni (in sostanza i \textit{grace
                            time}) delle quote del filesystem indicato
                          da \param{dev} sulla struttura \struct{dqinfo} 
                          puntata da \param{addr}, \param{id} viene ignorato.\\
    \const{Q\_SETINFO}  & Imposta le informazioni delle quote del filesystem
                          indicato da \param{dev} come ottenuti dalla
                          struttura \struct{dqinfo} puntata
                          da \param{addr}, \param{id} viene ignorato;  
                          l'operazione richiede i privilegi di amministratore.\\
    \const{Q\_GETFMT}   & Richiede il valore identificativo (quello di
                          tab.~\ref{tab:quotactl_id_format}) per il formato
                          delle quote attualmente in uso sul filesystem
                          indicato da \param{dev}, che sarà memorizzato
                          sul buffer di 4 byte puntato da \param{addr}.\\
    \const{Q\_SYNC}     & Aggiorna la copia su disco dei dati delle quote del
                          filesystem indicato da \param{dev}; in questo
                          caso \param{dev} può anche essere \val{NULL} nel
                          qual caso verranno aggiornati i dati per tutti i
                          filesystem con quote attive, \param{id}
                          e \param{addr} vengono comunque ignorati.\\ 
    \const{Q\_GETSTATS} & Ottiene statistiche ed altre informazioni generali 
                          relative al sistema delle quote per il filesystem
                          indicato da \param{dev}, richiede che si
                          passi come argomento \param{addr} l'indirizzo di una
                          struttura \struct{dqstats}, mentre i valori
                          di \param{id} e \param{dev} vengono ignorati;
                          l'operazione è obsoleta e non supportata nei kernel
                          più recenti, che espongono la stessa informazione
                          nei file sotto \procfile{/proc/self/fs/quota/}.\\
%    \const{} & .\\
    \hline
  \end{tabular}
  \caption{Possibili valori per l'argomento \param{subcmd} di
    \macro{QCMD}.} 
  \label{tab:quotactl_commands}
\end{table}


Le diverse operazioni supportate da \func{quotactl}, da indicare con
l'argomento \param{subcmd} di \macro{QCMD}, sono riportate in
tab.~\ref{tab:quotactl_commands}. In generale le operazione di attivazione,
disattivazione e di modifica dei limiti delle quote sono riservate e
richiedono i privilegi di amministratore.\footnote{per essere precisi tutte le
  operazioni indicate come privilegiate in tab.~\ref{tab:quotactl_commands}
  richiedono la \textit{capability} \const{CAP\_SYS\_ADMIN}.} Inoltre gli
utenti possono soltanto richiedere i dati relativi alle proprie quote, solo
l'amministratore può ottenere i dati di tutti.

\begin{table}[htb]
  \centering
  \footnotesize
  \begin{tabular}{|l|p{10cm}|}
    \hline
    \textbf{Identificatore} & \textbf{Descrizione} \\
    \hline
    \hline
    \const{QFMT\_VFS\_OLD}& il vecchio (ed obsoleto) formato delle quote.\\
    \const{QFMT\_VFS\_V0} & la versione 0 usata dal VFS di Linux (supporta
                            \ids{UID} e \ids{GID} a 32 bit e limiti fino a
                            $2^{42}$ byte e $2^{32}$ file.\\
    \const{QFMT\_VFS\_V1} & la versione 1 usata dal VFS di Linux (supporta
                            \ids{UID} e \ids{GID} a 32 bit e limiti fino a
                            $2^{64}$ byte e $2^{64}$ file.\\
    \hline
  \end{tabular}
  \caption{Valori di identificazione del formato delle quote.} 
  \label{tab:quotactl_id_format}
\end{table}

Alcuni dei comandi di tab.~\ref{tab:quotactl_commands} sono alquanto complessi
e richiedono un approfondimento maggiore, in particolare \const{Q\_GETQUOTA} e
\const{Q\_SETQUOTA} fanno riferimento ad una specifica struttura
\struct{dqblk}, la cui definizione è riportata in
fig.~\ref{fig:dqblk_struct},\footnote{la definizione mostrata è quella usata
  fino dal kernel 2.4.22, non prenderemo in considerazione le versioni
  obsolete.} nella quale vengono inseriti i dati relativi alle quote di un
singolo utente.

\begin{figure}[!htb]
  \footnotesize \centering
  \begin{minipage}[c]{\textwidth}
    \includestruct{listati/dqblk.h}
  \end{minipage} 
  \normalsize 
  \caption{La struttura \structd{dqblk} per i dati delle quote disco.}
  \label{fig:dqblk_struct}
\end{figure}

La struttura viene usata sia con \const{Q\_GETQUOTA} per ottenere i valori
correnti dei limiti e dell'occupazione delle risorse, che con
\const{Q\_SETQUOTA} per effettuare modifiche ai limiti; come si può notare ci
sono alcuni campi (in sostanza \val{dqb\_curspace}, \val{dqb\_curinodes},
\val{dqb\_btime}, \val{dqb\_itime}) che hanno senso solo in lettura in quanto
riportano uno stato non modificabile da \func{quotactl}, come l'uso corrente
di spazio e \itindex{inode} \textit{inode} o il tempo che resta nel caso si
sia superato un \textit{soft limit}.

\begin{table}[htb]
  \centering
  \footnotesize
  \begin{tabular}{|l|p{10cm}|}
    \hline
    \textbf{Costante} & \textbf{Descrizione} \\
    \hline
    \hline
    \const{QIF\_BLIMITS}& Limiti sui blocchi di 
                          spazio disco (\val{dqb\_bhardlimit} e
                          \val{dqb\_bsoftlimit}).\\
    \const{QIF\_SPACE}  & Uso corrente
                          dello spazio disco (\val{dqb\_curspace}).\\
    \const{QIF\_ILIMITS}& Limiti sugli \itindex{inode}  \textit{inode}
                          (\val{dqb\_ihardlimit} e \val{dqb\_isoftlimit}).\\
    \const{QIF\_INODES} & Uso corrente
                          degli \textit{inode} (\val{dqb\_curinodes}).\\
    \const{QIF\_BTIME}  & Tempo di
                          sforamento del \textit{soft limit} sul numero di
                          blocchi (\val{dqb\_btime}).\\
    \const{QIF\_ITIME}  & Tempo di
                          sforamento del \textit{soft limit} sul numero di
                          \itindex{inode} \textit{inode} (\val{dqb\_itime}).\\ 
    \const{QIF\_LIMITS} & L'insieme di \const{QIF\_BLIMITS} e
                          \const{QIF\_ILIMITS}.\\
    \const{QIF\_USAGE}  & L'insieme di \const{QIF\_SPACE} e
                          \const{QIF\_INODES}.\\
    \const{QIF\_TIMES}  & L'insieme di \const{QIF\_BTIME} e
                          \const{QIF\_ITIME}.\\ 
    \const{QIF\_ALL}    & Tutti i precedenti.\\
    \hline
  \end{tabular}
  \caption{Costanti per il campo \val{dqb\_valid} di \struct{dqblk}.} 
  \label{tab:quotactl_qif_const}
\end{table}


Inoltre in caso di modifica di un limite si può voler operare solo su una
delle risorse (blocchi o \itindex{inode} \textit{inode});\footnote{non è
  possibile modificare soltanto uno dei limiti (\textit{hard} o \textit{soft})
  occorre sempre rispecificarli entrambi.} per questo la struttura prevede un
campo apposito, \val{dqb\_valid}, il cui scopo è quello di indicare quali sono
gli altri campi che devono essere considerati validi. Questo campo è una
maschera binaria che deve essere espressa nei termini di OR aritmetico delle
apposite costanti di tab.~\ref{tab:quotactl_qif_const}, dove si è riportato il
significato di ciascuna di esse ed i campi a cui fanno riferimento.

In lettura con \const{Q\_SETQUOTA} eventuali valori presenti in \struct{dqblk}
vengono comunque ignorati, al momento la funzione sovrascrive tutti i campi e
li marca come validi in \val{dqb\_valid}. Si possono invece usare
\const{QIF\_BLIMITS} o \const{QIF\_ILIMITS} per richiedere di impostare solo
la rispettiva tipologia di limiti con \const{Q\_SETQUOTA}. Si tenga presente
che il sistema delle quote richiede che l'occupazione di spazio disco sia
indicata in termini di blocchi e non di byte; dato che questo dipende da come
si è creato il filesystem potrà essere necessario effettuare qualche
controllo.\footnote{in genere viene usato un default di 1024 byte per blocco,
  ma quando si hanno file di dimensioni medie maggiori può convenire usare
  valori più alti per ottenere prestazioni migliori in conseguenza di un
  minore frazionamento dei dati e di indici più corti.}

Altre due operazioni che necessitano di un approfondimento sono
\const{Q\_GETINFO} e \const{Q\_SETINFO}, che sostanzialmente consentono di
ottenere i dati relativi alle impostazioni delle altre proprietà delle quote,
che si riducono poi alla durata del \textit{grace time} per i due tipi di
limiti. In questo caso queste si proprietà generali sono identiche per tutti
gli utenti, per cui viene usata una operazione distinta dalle
precedenti. Anche in questo caso le due operazioni richiedono l'uso di una
apposita struttura \struct{dqinfo}, la cui definizione è riportata in
fig.~\ref{fig:dqinfo_struct}.

\begin{figure}[!htb]
  \footnotesize \centering
  \begin{minipage}[c]{\textwidth}
    \includestruct{listati/dqinfo.h}
  \end{minipage} 
  \normalsize 
  \caption{La struttura \structd{dqinfo} per i dati delle quote disco.}
  \label{fig:dqinfo_struct}
\end{figure}

Come per \struct{dqblk} anche in questo caso viene usato un campo della
struttura, \val{dqi\_valid} come maschera binaria per dichiarare quale degli
altri campi sono validi; le costanti usate per comporre questo valore sono
riportate in tab.~\ref{tab:quotactl_iif_const} dove si è riportato il
significato di ciascuna di esse ed i campi a cui fanno riferimento.

\begin{table}[htb]
  \centering
  \footnotesize
  \begin{tabular}{|l|l|}
    \hline
    \textbf{Costante} & \textbf{Descrizione} \\
    \hline
    \hline
    \const{IIF\_BGRACE}& Il \textit{grace period} per i blocchi
                         (\val{dqi\_bgrace}).\\
    \const{IIF\_IGRACE}& Il \textit{grace period} per gli \textit{inode} 
                         \itindex{inode} (\val{dqi\_igrace}).\\ 
    \const{IIF\_FLAGS} & I flag delle quote (\val{dqi\_flags}) (inusato ?).\\
    \const{IIF\_ALL}   & Tutti i precedenti.\\
    \hline
  \end{tabular}
  \caption{Costanti per il campo \val{dqi\_valid} di \struct{dqinfo}.} 
  \label{tab:quotactl_iif_const}
\end{table}

Come in precedenza con \const{Q\_GETINFO} tutti i valori vengono letti
sovrascrivendo il contenuto di \struct{dqinfo} e marcati come validi in
\val{dqi\_valid}. In scrittura con \const{Q\_SETINFO} si può scegliere quali
impostare, si tenga presente che i tempi dei campi \val{dqi\_bgrace} e
\val{dqi\_igrace} devono essere specificati in secondi.

Come esempi dell'uso di \func{quotactl} utilizzeremo estratti del codice di un
modulo Python usato per fornire una interfaccia diretta a \func{quotactl}
senza dover passare dalla scansione dei risultati di un comando. Il modulo si
trova fra i pacchetti Debian messi a disposizione da Truelite Srl,
all'indirizzo \url{http://labs.truelite.it/projects/packages}.\footnote{in
  particolare il codice C del modulo è nel file \texttt{quotamodule.c}
  visionabile a partire dall'indirizzo indicato nella sezione
  \textit{Repository}.}

\begin{figure}[!htbp]
  \footnotesize \centering
  \begin{minipage}[c]{\codesamplewidth}
    \includecodesample{listati/get_quota.c}
  \end{minipage}
  \caption{Esempio di codice per ottenere i dati delle quote.} 
  \label{fig:get_quota}
\end{figure}

Il primo esempio, riportato in fig.~\ref{fig:get_quota}, riporta il codice
della funzione che consente di leggere le quote. La funzione fa uso
dell'interfaccia dal C verso Python, che definisce i vari simboli \texttt{Py*}
(tipi di dato e funzioni). Non staremo ad approfondire i dettagli di questa
interfaccia, per la quale esistono numerose trattazioni dettagliate, ci
interessa solo esaminare l'uso di \func{quotactl}. 

In questo caso la funzione prende come argomenti (\texttt{\small 1}) l'intero
\texttt{who} che indica se si vuole operare sulle quote utente o gruppo,
l'identificatore \texttt{id} dell'utente o del gruppo scelto, ed il nome del
file di dispositivo del filesystem su cui si sono attivate le
quote.\footnote{questi vengono passati come argomenti dalle funzioni mappate
  come interfaccia pubblica del modulo (una per gruppi ed una per gli utenti)
  che si incaricano di decodificare i dati passati da una chiamata nel codice
  Python.} Questi argomenti vengono passati direttamente alla chiamata a
\func{quotactl} (\texttt{\small 5}), a parte \texttt{who} che viene abbinato
con \macro{QCMD} al comando \const{Q\_GETQUOTA} per ottenere i dati.

La funzione viene eseguita all'interno di un condizionale (\texttt{\small
  5--16}) che in caso di successo provvede a costruire (\texttt{\small 6--12})
opportunamente una risposta restituendo tramite la opportuna funzione di
interfaccia un oggetto Python contenente i dati della struttura \struct{dqblk}
relativi a uso corrente e limiti sia per i blocchi che per gli \itindex{inode} 
\textit{inode}. In caso di errore (\texttt{\small 13--15}) si usa un'altra
funzione dell'interfaccia per passare il valore di \var{errno} come eccezione.

\begin{figure}[!htbp]
  \footnotesize \centering
  \begin{minipage}[c]{\codesamplewidth}
    \includecodesample{listati/set_block_quota.c}
  \end{minipage}
  \caption{Esempio di codice per impostare i limiti sullo spazio disco.}
  \label{fig:set_block_quota}
\end{figure}

Per impostare i limiti sullo spazio disco si potrà usare una seconda funzione,
riportata in fig.~\ref{fig:set_block_quota}, che prende gli stessi argomenti
della precedente, con lo stesso significato, a cui si aggiungono i valori per
il \textit{soft limit} e l'\textit{hard limit}. In questo caso occorrerà,
prima di chiamare \func{quotactl}, inizializzare opportunamente
(\texttt{\small 5--7}) i campi della struttura \struct{dqblk} che si vogliono
utilizzare (quelli relativi ai limiti sui blocchi) e specificare gli stessi
con \const{QIF\_BLIMITS} in \var{dq.dqb\_valid}. 

Fatto questo la chiamata a \func{quotactl}, stavolta con il comando
\const{Q\_SETQUOTA}, viene eseguita come in precedenza all'interno di un
condizionale (\texttt{\small 9--14}). In questo caso non essendovi da
restituire nessun dato in caso di successo si usa (\texttt{\small 10}) una
apposita funzione di uscita, mentre si restituisce come prima una eccezione
con il valore di \var{errno} in caso di errore (\texttt{\small 12--13}).


\subsection{La gestione delle \textit{capabilities}}
\label{sec:proc_capabilities}

\itindbeg{capabilities} 

Come accennato in sez.~\ref{sec:proc_access_id} l'architettura classica della
gestione dei privilegi in un sistema unix-like ha il sostanziale problema di
fornire all'amministratore dei poteri troppo ampi, questo comporta che anche
quando si siano predisposte delle misure di protezione per in essere in grado
di difendersi dagli effetti di una eventuale compromissione del
sistema,\footnote{come montare un filesystem in sola lettura per impedirne
  modifiche, o marcare un file come immutabile.} una volta che questa sia
stata effettuata e si siano ottenuti i privilegi di amministratore, queste
potranno essere comunque rimosse.\footnote{nei casi elencati nella precedente
  nota si potrà sempre rimontare il sistema in lettura-scrittura, o togliere
  la marcatura di immutabilità.}

Il problema consiste nel fatto che nell'architettura tradizionale di un
sistema unix-like i controlli di accesso sono basati su un solo livello di
separazione: per i processi normali essi sono posti in atto, mentre per i
processi con i privilegi di amministratore essi non vengono neppure eseguiti;
per questo motivo non era previsto alcun modo per evitare che un processo con
diritti di amministratore non potesse eseguire certe operazioni, o per cedere
definitivamente alcuni privilegi da un certo momento in poi.

Per ovviare a tutto ciò, a partire dai kernel della serie 2.2, è stato
introdotto un meccanismo, detto \textit{capabilities}, che consentisse di
suddividere i vari privilegi tradizionalmente associati all'amministratore in
un insieme di \textsl{capacità} distinte.  L'idea era che queste capacità
potessero essere abilitate e disabilitate in maniera indipendente per ciascun
processo con privilegi di amministratore, permettendo così una granularità
molto più fine nella distribuzione degli stessi che evitasse la originaria
situazione di ``\textsl{tutto o nulla}''.

Il meccanismo completo delle \textit{capabilities}\footnote{l'implementazione
  si rifà ad una bozza di quello che doveva diventare lo standard POSIX.1e,
  poi abbandonato.} prevede inoltre la possibilità di associare le stesse ai
singoli file eseguibili, in modo da poter stabilire quali capacità possono
essere utilizzate quando viene messo in esecuzione uno specifico programma; ma
il supporto per questa funzionalità, chiamata \textit{file capabilities}, è
stato introdotto soltanto a partire dal kernel 2.6.24. Fino ad allora doveva
essere il programma stesso ad eseguire una riduzione esplicita delle sue
capacità, cosa che ha reso l'uso di questa funzionalità poco diffuso, vista la
presenza di meccanismi alternativi per ottenere limitazioni delle capacità
dell'amministratore a livello di sistema operativo, come \index{SELinux}
SELinux.

Con questo supporto e con le ulteriori modifiche introdotte con il kernel
2.6.25 il meccanismo delle \textit{capabilities} è stato totalmente
rivoluzionato, rendendolo più aderente alle intenzioni originali dello
standard POSIX, rimuovendo il significato che fino ad allora aveva avuto la
capacità \const{CAP\_SETPCAP} e cambiando le modalità di funzionamento del
cosiddetto \itindex{capabilities~bounding~set} \textit{capabilities bounding
  set}. Ulteriori modifiche sono state apportate con il kernel 2.6.26 per
consentire la rimozione non ripristinabile dei privilegi di
amministratore. Questo fa sì che il significato ed il comportamento del kernel
finisca per dipendere dalla versione dello stesso e dal fatto che le nuove
\textit{file capabilities} siano abilitate o meno. Per capire meglio la
situazione e cosa è cambiato conviene allora spiegare con maggiori dettagli
come funziona il meccanismo delle \textit{capabilities}.

Il primo passo per frazionare i privilegi garantiti all'amministratore,
supportato fin dalla introduzione iniziale del kernel 2.2, è stato quello in
cui a ciascun processo sono stati associati tre distinti insiemi di
\textit{capabilities}, denominati rispettivamente \textit{permitted},
\textit{inheritable} ed \textit{effective}. Questi insiemi vengono mantenuti
in forma di tre diverse maschere binarie,\footnote{il kernel li mantiene, come
  i vari identificatori di sez.~\ref{sec:proc_setuid}, all'interno della
  \struct{task\_struct} di ciascun processo (vedi
  fig.~\ref{fig:proc_task_struct}), nei tre campi \texttt{cap\_effective},
  \texttt{cap\_inheritable}, \texttt{cap\_permitted} del tipo
  \texttt{kernel\_cap\_t}; questo era, fino al kernel 2.6.25 definito come
  intero a 32 bit per un massimo di 32 \textit{capabilities} distinte,
  attualmente è stato aggiornato ad un vettore in grado di mantenerne fino a
  64.}  in cui ciascun bit corrisponde ad una capacità diversa. 

L'utilizzo di tre distinti insiemi serve a fornire una interfaccia flessibile
per l'uso delle \textit{capabilities}, con scopi analoghi a quelli per cui
sono mantenuti i diversi insiemi di identificatori di
sez.~\ref{sec:proc_setuid}; il loro significato, che è rimasto sostanzialmente
lo stesso anche dopo le modifiche seguite alla introduzione delle
\textit{file capabilities} è il seguente:
\begin{basedescript}{\desclabelwidth{2.1cm}\desclabelstyle{\nextlinelabel}}
\item[\textit{permitted}] l'insieme delle \textit{capabilities}
  ``\textsl{permesse}'', cioè l'insieme di quelle capacità che un processo
  \textsl{può} impostare come \textsl{effettive} o come
  \textsl{ereditabili}. Se un processo cancella una capacità da questo insieme
  non potrà più riassumerla.\footnote{questo nei casi ordinari, sono
    previste però una serie di eccezioni, dipendenti anche dal tipo di
    supporto, che vedremo meglio in seguito dato il notevole intreccio nella
    casistica.}
\item[\textit{inheritable}] l'insieme delle \textit{capabilities}
  ``\textsl{ereditabili}'', cioè di quelle che verranno trasmesse come insieme
  delle \textsl{permesse} ad un nuovo programma eseguito attraverso una
  chiamata ad \func{exec}.
\item[\textit{effective}] l'insieme delle \textit{capabilities}
  ``\textsl{effettive}'', cioè di quelle che vengono effettivamente usate dal
  kernel quando deve eseguire il controllo di accesso per le varie operazioni
  compiute dal processo.
\label{sec:capabilities_set}
\end{basedescript}

Con l'introduzione delle \textit{file capabilities} sono stati introdotti
altri tre insiemi associabili a ciascun file.\footnote{la realizzazione viene
  eseguita con l'uso di uno specifico attributo esteso,
  \texttt{security.capability}, la cui modifica è riservata, (come illustrato
  in sez.~\ref{sec:file_xattr}) ai processi dotato della capacità
  \const{CAP\_SYS\_ADMIN}.} Le \textit{file capabilities} hanno effetto
soltanto quando il file che le porta viene eseguito come programma con una
\func{exec}, e forniscono un meccanismo che consente l'esecuzione dello stesso
con maggiori privilegi; in sostanza sono una sorta di estensione del
\acr{suid} bit limitato ai privilegi di amministratore. Anche questi tre
insiemi sono identificati con gli stessi nomi di quello dei processi, ma il
loro significato è diverso:
\begin{basedescript}{\desclabelwidth{2.1cm}\desclabelstyle{\nextlinelabel}}
\item[\textit{permitted}] (chiamato originariamente \textit{forced}) l'insieme
  delle capacità che con l'esecuzione del programma verranno aggiunte alle
  capacità \textsl{permesse} del processo.
\item[\textit{inheritable}] (chiamato originariamente \textit{allowed})
  l'insieme delle capacità che con l'esecuzione del programma possono essere
  ereditate dal processo originario (che cioè non vengono tolte
  dall'\textit{inheritable set} del processo originale all'esecuzione di
  \func{exec}).
\item[\textit{effective}] in questo caso non si tratta di un insieme ma di un
  unico valore logico; se attivo all'esecuzione del programma tutte le
  capacità che risulterebbero \textsl{permesse} verranno pure attivate,
  inserendole automaticamente nelle \textsl{effettive}, se disattivato nessuna
  capacità verrà attivata (cioè l'\textit{effective set} resterà vuoto).
\end{basedescript}

\itindbeg{capabilities~bounding~set}

Infine come accennato, esiste un ulteriore insieme, chiamato
\textit{capabilities bounding set}, il cui scopo è quello di costituire un
limite alle capacità che possono essere attivate per un programma. Il suo
funzionamento però è stato notevolmente modificato con l'introduzione delle
\textit{file capabilities} e si deve pertanto prendere in considerazione una
casistica assai complessa.

Per i kernel fino al 2.6.25, o se non si attiva il supporto per le
\textit{file capabilities}, il \textit{capabilities bounding set} è un
parametro generale di sistema, il cui valore viene riportato nel file
\sysctlfile{kernel/cap-bound}. Il suo valore iniziale è definito in
sede di compilazione del kernel, e da sempre ha previsto come default la
presenza di tutte le \textit{capabilities} eccetto \const{CAP\_SETPCAP}. In
questa situazione solo il primo processo eseguito nel sistema (quello con
\textsl{pid} 1, di norma \texttt{/sbin/init}) ha la possibilità di
modificarlo; ogni processo eseguito successivamente, se dotato dei privilegi
di amministratore, è in grado soltanto di rimuovere una delle
\textit{capabilities} già presenti dell'insieme.\footnote{per essere precisi
  occorreva la capacità \const{CAP\_SYS\_MODULE}.}

In questo caso l'effetto complessivo del \textit{capabilities bounding set} è
che solo le capacità in esso presenti possono essere trasmesse ad un altro
programma attraverso una \func{exec}. Questo in sostanza significa che se un
qualunque programma elimina da esso una capacità, considerato che
\texttt{init} (almeno nelle versioni ordinarie) non supporta la reimpostazione
del \textit{bounding set}, questa non sarà più disponibile per nessun processo
a meno di un riavvio, eliminando così in forma definitiva quella capacità per
tutti, compreso l'amministratore.\footnote{la qual cosa, visto il default
  usato per il \textit{capabilities bounding set}, significa anche che
  \const{CAP\_SETPCAP} non è stata praticamente mai usata nella sua forma
  originale.}

Con il kernel 2.6.25 e le \textit{file capabilities} il \textit{bounding set}
è diventato una proprietà di ciascun processo, che viene propagata invariata
sia attraverso una \func{fork} che una \func{exec}. In questo caso il file
\sysctlfile{kernel/cap-bound} non esiste e \texttt{init} non ha nessun
ruolo speciale, inoltre in questo caso all'avvio il valore iniziale prevede la
presenza di tutte le capacità (compresa \const{CAP\_SETPCAP}). 

Con questo nuovo meccanismo il \textit{bounding set} continua a ricoprire un
ruolo analogo al precedente nel passaggio attraverso una \func{exec}, come
limite alle capacità che possono essere aggiunte al processo in quanto
presenti nel \textit{permitted set} del programma messo in esecuzione, in
sostanza il nuovo programma eseguito potrà ricevere una capacità presente nel
suo \textit{permitted set} (quello del file) solo se questa è anche nel
\textit{bounding set} (del processo). In questo modo si possono rimuovere
definitivamente certe capacità da un processo, anche qualora questo dovesse
eseguire un programma privilegiato che prevede di riassegnarle.

Si tenga presente però che in questo caso il \textit{bounding set} blocca
esclusivamente le capacità indicate nel \textit{permitted set} del programma
che verrebbero attivate in caso di esecuzione, e non quelle eventualmente già
presenti nell'\textit{inheritable set} del processo (ad esempio perché
presenti prima di averle rimosse dal \textit{bounding set}). In questo caso
eseguendo un programma che abbia anche lui dette capacità nel suo
\textit{inheritable set} queste verrebbero assegnate.

In questa seconda versione inoltre il \textit{bounding set} costituisce anche
un limite per le capacità che possono essere aggiunte all'\textit{inheritable
  set} del processo stesso con \func{capset}, sempre nel senso che queste
devono essere presenti nel \textit{bounding set} oltre che nel
\textit{permitted set} del processo. Questo limite vale anche per processi con
i privilegi di amministratore,\footnote{si tratta sempre di avere la
  \textit{capability} \const{CAP\_SETPCAP}.} per i quali invece non vale la
condizione che le \textit{capabilities} da aggiungere nell'\textit{inheritable
  set} debbano essere presenti nel proprio \textit{permitted set}.\footnote{lo
  scopo anche in questo caso è ottenere una rimozione definitiva della
  possibilità di passare una capacità rimossa dal \textit{bounding set}.}

Come si può notare per fare ricorso alle \textit{capabilities} occorre
comunque farsi carico di una notevole complessità di gestione, aggravata dalla
presenza di una radicale modifica del loro funzionamento con l'introduzione
delle \textit{file capabilities}. Considerato che il meccanismo originale era
incompleto e decisamente problematico nel caso di programmi che non ne
sapessero tener conto,\footnote{c'è stato un grosso problema di sicurezza con
  \texttt{sendmail}, riuscendo a rimuovere \const{CAP\_SETGID}
  dall'\textit{inheritable set} di un processo si ottenne di far fallire
  \func{setuid} in maniera inaspettata per il programma (che aspettandosi
  sempre il successo della funzione non ne controllava lo stato di uscita) con
  la conseguenza di effettuare come amministratore operazioni che altrimenti
  sarebbero state eseguite, senza poter apportare danni, da utente normale.}
ci soffermeremo solo sulla implementazione completa presente a partire dal
kernel 2.6.25, tralasciando ulteriori dettagli riguardo la versione
precedente.

Riassumendo le regole finora illustrate tutte le \textit{capabilities} vengono
ereditate senza modifiche attraverso una \func{fork} mentre, indicati con
\texttt{orig\_*} i valori degli insiemi del processo chiamante, con
\texttt{file\_*} quelli del file eseguito e con \texttt{bound\_set} il
\textit{capabilities bounding set}, dopo l'invocazione di \func{exec} il
processo otterrà dei nuovi insiemi di capacità \texttt{new\_*} secondo la
formula (espressa in pseudo-codice C) di fig.~\ref{fig:cap_across_exec}; si
noti come in particolare il \textit{capabilities bounding set} non viene
comunque modificato e resta lo stesso sia attraverso una \func{fork} che
attraverso una \func{exec}.

\begin{figure}[!htbp]
  \footnotesize \centering
  \begin{minipage}[c]{12cm}
    \includecodesnip{listati/cap-results.c}
  \end{minipage}
  \caption{Espressione della modifica delle \textit{capabilities} attraverso
    una \func{exec}.}
  \label{fig:cap_across_exec}
\end{figure}

\itindend{capabilities~bounding~set}

A queste regole se ne aggiungono delle altre che servono a riprodurre il
comportamento tradizionale di un sistema unix-like in tutta una serie di
circostanze. La prima di queste è relativa a quello che avviene quando si
esegue un file senza \textit{capabilities}; se infatti si considerasse questo
equivalente al non averne assegnata alcuna, non essendo presenti capacità né
nel \textit{permitted set} né nell'\textit{inheritable set} del file,
nell'esecuzione di un qualunque programma l'amministratore perderebbe tutti i
privilegi originali dal processo.

Per questo motivo se un programma senza \textit{capabilities} assegnate viene
eseguito da un processo con \ids{UID} reale 0, esso verrà trattato come
se tanto il \textit{permitted set} che l'\textit{inheritable set} fossero con
tutte le \textit{capabilities} abilitate, con l'\textit{effective set} attivo,
col risultato di fornire comunque al processo tutte le capacità presenti nel
proprio \textit{bounding set}. Lo stesso avviene quando l'eseguibile ha attivo
il \acr{suid} bit ed appartiene all'amministratore, in entrambi i casi si
riesce così a riottenere il comportamento classico di un sistema unix-like.

Una seconda circostanza è quella relativa a cosa succede alle
\textit{capabilities} di un processo nelle possibili transizioni da \ids{UID}
nullo a \ids{UID} non nullo o viceversa (corrispondenti rispettivamente a
cedere o riottenere i i privilegi di amministratore) che si possono effettuare
con le varie funzioni viste in sez.~\ref{sec:proc_setuid}. In questo caso la
casistica è di nuovo alquanto complessa, considerata anche la presenza dei
diversi gruppi di identificatori illustrati in tab.~\ref{tab:proc_uid_gid}, si
avrà allora che:
\begin{enumerate*}
\item se si passa da \ids{UID} effettivo nullo a non nullo
  l'\textit{effective set} del processo viene totalmente azzerato, se
  viceversa si passa da \ids{UID} effettivo non nullo a nullo il
  \textit{permitted set} viene copiato nell'\textit{effective set};
\item se si passa da \textit{file system} \ids{UID} nullo a non nullo verranno
  cancellate dall'\textit{effective set} del processo tutte le capacità
  attinenti i file, e cioè \const{CAP\_LINUX\_IMMUTABLE}, \const{CAP\_MKNOD},
  \const{CAP\_DAC\_OVERRIDE}, \const{CAP\_DAC\_READ\_SEARCH},
  \const{CAP\_MAC\_OVERRIDE}, \const{CAP\_CHOWN}, \const{CAP\_FSETID} e
  \const{CAP\_FOWNER} (le prime due a partire dal kernel 2.2.30), nella
  transizione inversa verranno invece inserite nell'\textit{effective set}
  quelle capacità della precedente lista che sono presenti nel suo
  \textit{permitted set}.
\item se come risultato di una transizione riguardante gli identificativi dei
  gruppi \textit{real}, \textit{saved} ed \textit{effective} in cui si passa
  da una situazione in cui uno di questi era nullo ad una in cui sono tutti
  non nulli,\footnote{in sostanza questo è il caso di quando si chiama
    \func{setuid} per rimuovere definitivamente i privilegi di amministratore
    da un processo.} verranno azzerati completamente sia il \textit{permitted
    set} che l'\textit{effective set}.
\end{enumerate*}
\label{sec:capability-uid-transition}

La combinazione di tutte queste regole consente di riprodurre il comportamento
ordinario di un sistema di tipo Unix tradizionale, ma può risultare
problematica qualora si voglia passare ad una configurazione di sistema
totalmente basata sull'applicazione delle \textit{capabilities}; in tal caso
infatti basta ad esempio eseguire un programma con \acr{suid} bit di proprietà
dell'amministratore per far riottenere ad un processo tutte le capacità
presenti nel suo \textit{bounding set}, anche se si era avuta la cura di
cancellarle dal \textit{permitted set}.

\itindbeg{securebits}

Per questo motivo a partire dal kernel 2.6.26, se le \textit{file
  capabilities} sono abilitate, ad ogni processo viene stata associata una
ulteriore maschera binaria, chiamata \textit{securebits flags}, su cui sono
mantenuti una serie di flag (vedi tab.~\ref{tab:securebits_values}) il cui
valore consente di modificare queste regole speciali che si applicano ai
processi con \ids{UID} nullo. La maschera viene sempre mantenuta
attraverso una \func{fork}, mentre attraverso una \func{exec} viene sempre
cancellato il flag \const{SECURE\_KEEP\_CAPS}.

\begin{table}[htb]
  \centering
  \footnotesize
  \begin{tabular}{|l|p{10cm}|}
    \hline
    \textbf{Flag} & \textbf{Descrizione} \\
    \hline
    \hline
    \const{SECURE\_KEEP\_CAPS}& Il processo non subisce la cancellazione delle
                                sue \textit{capabilities} quando tutti i suoi
                                \ids{UID} passano ad un valore non
                                nullo (regola di compatibilità per il cambio
                                di \ids{UID} n.~3 del precedente
                                elenco), sostituisce il precedente uso
                                dell'operazione \const{PR\_SET\_KEEPCAPS} di
                                \func{prctl}.\\
    \const{SECURE\_NO\_SETUID\_FIXUP}&Il processo non subisce le modifiche
                                delle sue \textit{capabilities} nel passaggio
                                da nullo a non nullo degli \ids{UID}
                                dei gruppi \textit{effective} e
                                \textit{file system} (regole di compatibilità
                                per il cambio di \ids{UID} nn.~1 e 2 del
                                precedente elenco).\\
    \const{SECURE\_NOROOT}    & Il processo non assume nessuna capacità
                                aggiuntiva quando esegue un programma, anche
                                se ha \ids{UID} nullo o il programma ha
                                il \acr{suid} bit attivo ed appartiene
                                all'amministratore (regola di compatibilità
                                per l'esecuzione di programmi senza
                                \textit{capabilities}).\\
    \hline
  \end{tabular}
  \caption{Costanti identificative dei flag che compongono la maschera dei
    \textit{securebits}.}  
  \label{tab:securebits_values}
\end{table}

A ciascuno dei flag di tab.~\ref{tab:securebits_values} è inoltre abbinato un
corrispondente flag di blocco, identificato da una costante omonima con
l'estensione \texttt{\_LOCKED}, la cui attivazione è irreversibile ed ha
l'effetto di rendere permanente l'impostazione corrente del corrispondente
flag ordinario; in sostanza con \const{SECURE\_KEEP\_CAPS\_LOCKED} si rende
non più modificabile \const{SECURE\_KEEP\_CAPS}, ed analogamente avviene con
\const{SECURE\_NO\_SETUID\_FIXUP\_LOCKED} per
\const{SECURE\_NO\_SETUID\_FIXUP} e con \const{SECURE\_NOROOT\_LOCKED} per
\const{SECURE\_NOROOT}.

Per l'impostazione di questi flag sono stata predisposte due specifiche
operazioni di \func{prctl} (vedi sez.~\ref{sec:process_prctl}),
\const{PR\_GET\_SECUREBITS}, che consente di ottenerne il valore, e
\const{PR\_SET\_SECUREBITS}, che consente di modificarne il valore; per
quest'ultima sono comunque necessari i privilegi di amministratore ed in
particolare la capacità \const{CAP\_SETPCAP}. Prima dell'introduzione dei
\textit{securebits} era comunque possibile ottenere lo stesso effetto di
\const{SECURE\_KEEP\_CAPS} attraverso l'uso di un'altra operazione di
\func{prctl}, \const{PR\_SET\_KEEPCAPS}.

\itindend{securebits}

Oltre alla gestione dei \textit{securebits} la nuova versione delle
\textit{file capabilities} prevede l'uso di \func{prctl} anche per la gestione
del \textit{capabilities bounding set}, attraverso altre due operazioni
dedicate, \const{PR\_CAPBSET\_READ} per controllarne il valore e
\const{PR\_CAPBSET\_DROP} per modificarlo; quest'ultima di nuovo è una
operazione privilegiata che richiede la capacità \const{CAP\_SETPCAP} e che,
come indica chiaramente il nome, permette solo la rimozione di una
\textit{capability} dall'insieme; per i dettagli sull'uso di tutte queste
operazioni si rimanda alla rilettura di sez.~\ref{sec:process_prctl}.

% TODO verificare per process capability bounding set, vedi:
%  http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=3b7391de67da515c91f48aa371de77cb6cc5c07e

% TODO capire cosa cambia con i patch vari, vedi
% http://lwn.net/Articles/280279/  
% http://lwn.net/Articles/256519/
% http://lwn.net/Articles/211883/


Un elenco delle delle \textit{capabilities} disponibili su Linux, con una
breve descrizione ed il nome delle costanti che le identificano, è riportato
in tab.~\ref{tab:proc_capabilities};\footnote{l'elenco presentato questa
  tabella, ripreso dalla pagina di manuale (accessibile con \texttt{man
    capabilities}) e dalle definizioni in
  \texttt{include/linux/capabilities.h}, è aggiornato al kernel 2.6.26.} la
tabella è divisa in due parti, la prima riporta le \textit{capabilities}
previste anche nella bozza dello standard POSIX1.e, la seconda quelle
specifiche di Linux.  Come si può notare dalla tabella alcune
\textit{capabilities} attengono a singole funzionalità e sono molto
specializzate, mentre altre hanno un campo di applicazione molto vasto, che è
opportuno dettagliare maggiormente.

\begin{table}[!h!btp]
  \centering
  \footnotesize
  \begin{tabular}{|l|p{10.5cm}|}
    \hline
    \textbf{Capacità}&\textbf{Descrizione}\\
    \hline
    \hline
%
% POSIX-draft defined capabilities.
%
    \const{CAP\_AUDIT\_CONTROL}& La capacità di abilitare e disabilitare il
                              controllo dell'auditing (dal kernel 2.6.11).\\ 
    \const{CAP\_AUDIT\_WRITE}&La capacità di scrivere dati nel giornale di
                              auditing del kernel (dal kernel 2.6.11).\\ 
    % TODO verificare questa roba dell'auditing
    \const{CAP\_CHOWN}      & La capacità di cambiare proprietario e gruppo
                              proprietario di un file (vedi
                              sez.~\ref{sec:file_ownership_management}).\\
    \const{CAP\_DAC\_OVERRIDE}& La capacità di evitare il controllo dei
                              permessi di lettura, scrittura ed esecuzione dei
                              file,\footnotemark (vedi
                              sez.~\ref{sec:file_access_control}).\\
    \const{CAP\_DAC\_READ\_SEARCH}& La capacità di evitare il controllo dei
                              permessi di lettura ed esecuzione per
                              le directory (vedi
                              sez.~\ref{sec:file_access_control}).\\
    \const{CAP\_FOWNER}     & La capacità di evitare il controllo della
                              proprietà di un file per tutte
                              le operazioni privilegiate non coperte dalle
                              precedenti \const{CAP\_DAC\_OVERRIDE} e
                              \const{CAP\_DAC\_READ\_SEARCH}.\\
    \const{CAP\_FSETID}     & La capacità di evitare la cancellazione
                              automatica dei bit \itindex{suid~bit} \acr{suid}
                              e \itindex{sgid~bit} \acr{sgid} quando un file
                              per i quali sono impostati viene modificato da
                              un processo senza questa capacità e la capacità
                              di impostare il bit \acr{sgid} su un file anche
                              quando questo è relativo ad un gruppo cui non si
                              appartiene (vedi
                              sez.~\ref{sec:file_perm_management}).\\ 
    \const{CAP\_KILL}       & La capacità di mandare segnali a qualunque
                              processo (vedi sez.~\ref{sec:sig_kill_raise}).\\
    \const{CAP\_SETFCAP}    & La capacità di impostare le
                              \textit{capabilities} di un file (dal kernel
                              2.6.24).\\  
    \const{CAP\_SETGID}     & La capacità di manipolare i group ID dei
                              processi, sia il principale che i supplementari,
                              (vedi sez.~\ref{sec:proc_setgroups}) che quelli
                              trasmessi tramite i socket \textit{unix domain}
                              (vedi sez.~\ref{sec:unix_socket}).\\
    \const{CAP\_SETUID}     & La capacità di manipolare gli user ID del
                              processo (vedi sez.~\ref{sec:proc_setuid}) e di
                              trasmettere un user ID arbitrario nel passaggio
                              delle credenziali coi socket \textit{unix
                                domain} (vedi sez.~\ref{sec:unix_socket}).\\ 
%
% Linux specific capabilities
%
\hline
    \const{CAP\_IPC\_LOCK}  & La capacità di effettuare il \textit{memory
                              locking} \itindex{memory~locking} con le
                              funzioni \func{mlock}, \func{mlockall},
                              \func{shmctl}, \func{mmap} (vedi
                              sez.~\ref{sec:proc_mem_lock} e 
                              sez.~\ref{sec:file_memory_map}). \\  
    \const{CAP\_IPC\_OWNER} & La capacità di evitare il controllo dei permessi
                              per le operazioni sugli oggetti di
                              intercomunicazione fra processi (vedi
                              sez.~\ref{sec:ipc_sysv}).\\  
    \const{CAP\_LEASE}      & La capacità di creare dei \textit{file lease}
                              \itindex{file~lease} (vedi
                              sez.~\ref{sec:file_asyncronous_lease})
                              pur non essendo proprietari del file (dal kernel
                              2.4).\\ 
    \const{CAP\_LINUX\_IMMUTABLE}& La capacità di impostare sui file gli
                              attributi \textit{immutable} e
                              \itindex{append~mode} \textit{append only} (se
                              supportati).\\
    \const{CAP\_MKNOD}      & La capacità di creare
                              \index{file!di~dispositivo} file di dispositivo
                              con \func{mknod} (vedi
                              sez.~\ref{sec:file_mknod}) (dal kernel 2.4).\\ 
    \const{CAP\_NET\_ADMIN} & La capacità di eseguire alcune operazioni
                              privilegiate sulla rete.\\
    \const{CAP\_NET\_BIND\_SERVICE}& La capacità di porsi in ascolto
                              su porte riservate (vedi
                              sez.~\ref{sec:TCP_func_bind}).\\ 
    \const{CAP\_NET\_BROADCAST}& La capacità di consentire l'uso di socket in
                              \itindex{broadcast} \textit{broadcast} e
                              \itindex{multicast} \textit{multicast}.\\ 
    \const{CAP\_NET\_RAW}   & La capacità di usare socket \texttt{RAW} e
                              \texttt{PACKET} (vedi sez.~\ref{sec:sock_type}).\\
    \const{CAP\_SETPCAP}    & La capacità di modifiche privilegiate alle
                              \textit{capabilities}.\\   
    \const{CAP\_SYS\_ADMIN} & La capacità di eseguire una serie di compiti
                              amministrativi.\\
    \const{CAP\_SYS\_BOOT}  & La capacità di fare eseguire un riavvio del
                              sistema (vedi sez.~\ref{sec:sys_reboot}).\\
    \const{CAP\_SYS\_CHROOT}& La capacità di eseguire la funzione
                              \func{chroot} (vedi sez.~\ref{sec:file_chroot}).\\
    \const{CAP\_MAC\_ADMIN} & La capacità amministrare il \textit{Mandatory
                               Access Control} di Smack (dal kernel 2.6.25).\\  
    \const{CAP\_MAC\_OVERRIDE}& La capacità evitare il  \textit{Mandatory
                               Access Control} di Smack (dal kernel 2.6.25).\\  
    \const{CAP\_SYS\_MODULE}& La capacità di caricare e rimuovere moduli del
                              kernel.\\ 
    \const{CAP\_SYS\_NICE}  & La capacità di modificare le varie priorità dei
                              processi (vedi sez.~\ref{sec:proc_priority}).\\
    \const{CAP\_SYS\_PACCT} & La capacità di usare le funzioni di
                              \textit{accounting} dei processi (vedi
                              sez.~\ref{sec:sys_bsd_accounting}).\\ 
    \const{CAP\_SYS\_PTRACE}& La capacità di tracciare qualunque processo con
                              \func{ptrace} (vedi 
                              sez.~\ref{sec:process_ptrace}).\\
    \const{CAP\_SYS\_RAWIO} & La capacità di operare sulle porte
                              di I/O con \func{ioperm} e \func{iopl} (vedi
                              sez.~\ref{sec:process_io_port}).\\
    \const{CAP\_SYS\_RESOURCE}& La capacità di superare le varie limitazioni
                              sulle risorse.\\ 
    \const{CAP\_SYS\_TIME}  & La capacità di modificare il tempo di sistema
                              (vedi sez.~\ref{sec:sys_time}).\\ 
    \const{CAP\_SYS\_TTY\_CONFIG}& La capacità di simulare un \textit{hangup}
                              della console, con la funzione
                              \func{vhangup}.\\
    \const{CAP\_SYSLOG}     & La capacità di gestire il buffer dei messaggi
                              del kernel, (vedi sez.~\ref{sec:sess_daemon}),
                              introdotta dal kernel 2.6.38 come capacità
                              separata da \const{CAP\_SYS\_ADMIN}.\\
    \const{CAP\_WAKE\_ALARM}& La capacità di usare i timer di tipo
                              \const{CLOCK\_BOOTTIME\_ALARM} e
                              \const{CLOCK\_REALTIME\_ALARM}, vedi
                              sez.~\ref{sec:sig_timer_adv} (dal kernel 3.0).\\  
    \hline
  \end{tabular}
  \caption{Le costanti che identificano le \textit{capabilities} presenti nel
    kernel.}
\label{tab:proc_capabilities}
\end{table}

\footnotetext{vale a dire i permessi caratteristici del modello classico del
  controllo di accesso chiamato \itindex{Discrectionary~Access~Control~(DAC)}
  \textit{Discrectionary Access Control} (da cui il nome DAC).}


Prima di dettagliare il significato della capacità più generiche, conviene
però dedicare un discorso a parte a \const{CAP\_SETPCAP}, il cui significato è
stato completamente cambiato con l'introduzione delle \textit{file
  capabilities} nel kernel 2.6.24. In precedenza questa capacità era quella
che permetteva al processo che la possedeva di impostare o rimuovere le
\textit{capabilities} che fossero presenti nel \textit{permitted set} del
chiamante di un qualunque altro processo. In realtà questo non è mai stato
l'uso inteso nelle bozze dallo standard POSIX, ed inoltre, come si è già
accennato, dato che questa capacità è assente nel \textit{capabilities
  bounding set} usato di default, essa non è neanche mai stata realmente
disponibile.

Con l'introduzione \textit{file capabilities} e il cambiamento del significato
del \textit{capabilities bounding set} la possibilità di modificare le
capacità di altri processi è stata completamente rimossa, e
\const{CAP\_SETPCAP} ha acquisito quello che avrebbe dovuto essere il suo
significato originario, e cioè la capacità del processo di poter inserire nel
suo \textit{inheritable set} qualunque capacità presente nel \textit{bounding
  set}. Oltre a questo la disponibilità di \const{CAP\_SETPCAP} consente ad un
processo di eliminare una capacità dal proprio \textit{bounding set} (con la
conseguente impossibilità successiva di eseguire programmi con quella
capacità), o di impostare i \textit{securebits} delle \textit{capabilities}.

La prima fra le capacità ``\textsl{ampie}'' che occorre dettagliare
maggiormente è \const{CAP\_FOWNER}, che rimuove le restrizioni poste ad un
processo che non ha la proprietà di un file in un vasto campo di
operazioni;\footnote{vale a dire la richiesta che l'\ids{UID} effettivo del
  processo (o meglio l'\ids{UID} di filesystem, vedi
  sez.~\ref{sec:proc_setuid}) coincida con quello del proprietario.}  queste
comprendono i cambiamenti dei permessi e dei tempi del file (vedi
sez.~\ref{sec:file_perm_management} e sez.~\ref{sec:file_file_times}), le
impostazioni degli attributi dei file (vedi sez.~\ref{sec:file_ioctl}) e delle
ACL (vedi sez.~\ref{sec:file_xattr} e \ref{sec:file_ACL}), poter ignorare lo
\itindex{sticky~bit} \textit{sticky bit} nella cancellazione dei file (vedi
sez.~\ref{sec:file_special_perm}), la possibilità di impostare il flag di
\const{O\_NOATIME} con \func{open} e \func{fcntl} (vedi
sez.~\ref{sec:file_open} e sez.~\ref{sec:file_fcntl}) senza restrizioni.

Una seconda capacità che copre diverse operazioni, in questo caso riguardanti
la rete, è \const{CAP\_NET\_ADMIN}, che consente di impostare le opzioni
privilegiate dei socket (vedi sez.~\ref{sec:sock_generic_options}), abilitare
il \itindex{multicast} \textit{multicasting}, eseguire la configurazione delle
interfacce di rete (vedi sez.~\ref{sec:sock_ioctl_netdevice}) ed impostare la
tabella di instradamento.

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: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
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
sez.~\ref{sec:io_priority}), superare il limite di sistema sul numero massimo
di file aperti,\footnote{quello indicato da \sysctlfile{fs/file-max}.}
effettuare operazioni privilegiate sulle chiavi mantenute dal kernel (vedi
sez.~\ref{sec:keyctl_management}), usare la funzione \func{lookup\_dcookie},
usare \const{CLONE\_NEWNS} con \func{unshare} e \func{clone}, (vedi
sez.~\ref{sec:process_clone}).

Originariamente \const{CAP\_SYS\_NICE} riguardava soltanto la capacità di
aumentare le priorità di esecuzione dei processi, come la diminuzione del
valore di \textit{nice} (vedi sez.~\ref{sec:proc_sched_stand}), l'uso delle
priorità \textit{real-time} (vedi sez.~\ref{sec:proc_real_time}), o
l'impostazione delle affinità di processore (vedi
sez.~\ref{sec:proc_sched_multiprocess}); ma con l'introduzione di priorità
anche riguardo le operazioni di accesso al disco, e, nel caso di sistemi NUMA,
alla memoria, essa viene a coprire anche la possibilità di assegnare priorità
arbitrarie nell'accesso a disco (vedi sez.~\ref{sec:io_priority}) e nelle
politiche di allocazione delle pagine di memoria ai nodi di un sistema NUMA.

Infine la \textit{capability} \const{CAP\_SYS\_RESOURCE} attiene alla
possibilità di superare i limiti imposti sulle risorse di sistema, come usare
lo spazio disco riservato all'amministratore sui filesystem che lo supportano,
usare la funzione \func{ioctl} per controllare il \textit{journaling} sul
filesystem \acr{ext3}, non subire le quote disco, aumentare i limiti sulle
risorse di un processo (vedi sez.~\ref{sec:sys_resource_limit}) e quelle sul
numero di processi, ed i limiti sulle dimensioni dei messaggi delle code del
SysV IPC (vedi sez.~\ref{sec:ipc_sysv_mq}).

Per la gestione delle \textit{capabilities} il kernel mette a disposizione due
funzioni che permettono rispettivamente di leggere ed impostare i valori dei
tre insiemi illustrati in precedenza. Queste due funzioni sono \funcd{capget}
e \funcd{capset} e costituiscono l'interfaccia di gestione basso livello; i
loro rispettivi prototipi sono:
\begin{functions}
  \headdecl{sys/capability.h}

  \funcdecl{int capget(cap\_user\_header\_t hdrp, cap\_user\_data\_t datap)}
  Legge le \textit{capabilities}.

  \funcdecl{int capset(cap\_user\_header\_t hdrp, const cap\_user\_data\_t
    datap)} 
  Imposta le \textit{capabilities}.

  
  \bodydesc{Entrambe le funzioni ritornano 0 in caso di successo e -1 in caso
    di errore, nel qual caso \var{errno} può assumere i valori:
    \begin{errlist}
    \item[\errcode{ESRCH}] si è fatto riferimento ad un processo inesistente.
    \item[\errcode{EPERM}] si è tentato di aggiungere una capacità
      nell'insieme delle \textit{capabilities} permesse, o di impostare una
      capacità non presente nell'insieme di quelle permesse negli insieme
      delle effettive o ereditate, o si è cercato di impostare una
      \textit{capability} di un altro processo senza avare
      \const{CAP\_SETPCAP}. 
  \end{errlist}
  ed inoltre \errval{EFAULT} ed \errval{EINVAL}.
}
\end{functions}

Queste due funzioni prendono come argomenti due tipi di dati dedicati,
definiti come puntatori a due strutture specifiche di Linux, illustrate in
fig.~\ref{fig:cap_kernel_struct}.  Per un certo periodo di tempo era anche
indicato che per poterle utilizzare fosse necessario che la macro
\macro{\_POSIX\_SOURCE} risultasse non definita (ed era richiesto di inserire
una istruzione \texttt{\#undef \_POSIX\_SOURCE} prima di includere
\headfile{sys/capability.h}) requisito che non risulta più
presente.\footnote{e non è chiaro neanche quanto sia mai stato davvero
  necessario.}

Si tenga presente che le strutture di fig.~\ref{fig:cap_kernel_struct}, come i
prototipi delle due funzioni \func{capget} e \func{capset}, sono soggette ad
essere modificate con il cambiamento del kernel (in particolare i tipi di dati
delle strutture) ed anche se finora l'interfaccia è risultata stabile, non c'è
nessuna assicurazione che questa venga mantenuta,\footnote{viene però
  garantito che le vecchie funzioni continuino a funzionare.} Pertanto se si
vogliono scrivere programmi portabili che possano essere eseguiti senza
modifiche o adeguamenti su qualunque versione del kernel è opportuno
utilizzare le interfacce di alto livello che vedremo più avanti.

\begin{figure}[!htb]
  \footnotesize
  \centering
  \begin{minipage}[c]{\textwidth}
    \includestruct{listati/cap_user_header_t.h}
  \end{minipage} 
  \normalsize 
  \caption{Definizione delle strutture a cui fanno riferimento i puntatori
    \structd{cap\_user\_header\_t} e \structd{cap\_user\_data\_t} usati per
    l'interfaccia di gestione di basso livello delle \textit{capabilities}.}
  \label{fig:cap_kernel_struct}
\end{figure}

La struttura a cui deve puntare l'argomento \param{hdrp} serve ad indicare,
tramite il campo \var{pid}, il PID del processo del quale si vogliono leggere
o modificare le \textit{capabilities}. Con \func{capset} questo, se si usano
le \textit{file capabilities}, può essere solo 0 o PID del processo chiamante,
che sono equivalenti. Il campo \var{version} deve essere impostato al valore
della versione delle stesse usata dal kernel (quello indicato da una delle
costanti \texttt{\_LINUX\_CAPABILITY\_VERSION\_n} di
fig.~\ref{fig:cap_kernel_struct}) altrimenti le funzioni ritorneranno con un
errore di \errcode{EINVAL}, restituendo nel campo stesso il valore corretto
della versione in uso. La versione due è comunque deprecata e non deve essere
usata (il kernel stamperà un avviso). I valori delle \textit{capabilities}
devono essere passati come maschere binarie;\footnote{e si tenga presente che
  i valori di tab.~\ref{tab:proc_capabilities} non possono essere combinati
  direttamente, indicando il numero progressivo del bit associato alla
  relativa capacità.} con l'introduzione delle \textit{capabilities} a 64 bit
inoltre il puntatore \param{datap} non può essere più considerato come
relativo ad una singola struttura, ma ad un vettore di due
strutture.\footnote{è questo cambio di significato che ha portato a deprecare
  la versione 2, che con \func{capget} poteva portare ad un buffer overflow
  per vecchie applicazioni che continuavano a considerare \param{datap} come
  puntatore ad una singola struttura.}

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 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
libreria attraverso l'opzione \texttt{-lcap} del compilatore.

Le funzioni dell'interfaccia delle bozze di POSIX.1e prevedono l'uso di un
\index{tipo!opaco} tipo di dato opaco, \type{cap\_t}, come puntatore ai dati
mantenuti nel cosiddetto \textit{capability state},\footnote{si tratta in
  sostanza di un puntatore ad una struttura interna utilizzata dalle librerie,
  i cui campi non devono mai essere acceduti direttamente.} in sono
memorizzati tutti i dati delle \textit{capabilities}. In questo modo è
possibile mascherare i dettagli della gestione di basso livello, che potranno
essere modificati senza dover cambiare le funzioni dell'interfaccia, che
faranno riferimento soltanto ad oggetti di questo tipo.  L'interfaccia
pertanto non soltanto fornisce le funzioni per modificare e leggere le
\textit{capabilities}, ma anche quelle per gestire i dati attraverso
\type{cap\_t}.

La prima funzione dell'interfaccia è quella che permette di inizializzare un
\textit{capability state}, allocando al contempo la memoria necessaria per i
relativi dati. La funzione è \funcd{cap\_init} ed il suo prototipo è:
\begin{functions}
  \headdecl{sys/capability.h}

  \funcdecl{cap\_t cap\_init(void)} 
  Crea ed inizializza un \textit{capability state}.
  
  \bodydesc{La funzione ritorna un valore non nullo in caso di successo e
    \val{NULL} in caso di errore, nel qual caso \var{errno} assumerà il
    valore \errval{ENOMEM}.
  }
\end{functions}

La funzione restituisce il puntatore \type{cap\_t} ad uno stato inizializzato
con tutte le \textit{capabilities} azzerate. In caso di errore (cioè quando
non c'è memoria sufficiente ad allocare i dati) viene restituito \val{NULL}
ed \var{errno} viene impostata a \errval{ENOMEM}.  La memoria necessaria a
mantenere i dati viene automaticamente allocata da \func{cap\_init}, ma dovrà
essere disallocata esplicitamente quando non è più necessaria utilizzando, per
questo l'interfaccia fornisce una apposita funzione, \funcd{cap\_free}, il cui
prototipo è:
\begin{functions}
  \headdecl{sys/capability.h}

  \funcdecl{int cap\_free(void *obj\_d)} 
  Disalloca la memoria allocata per i dati delle \textit{capabilities}.
  
  \bodydesc{La funzione ritorna 0 in caso di successo e $-1$ in caso di
    errore, nel qual caso \var{errno} assumerà il valore \errval{EINVAL}.
  }
\end{functions}

La funzione permette di liberare la memoria allocata dalle altre funzioni
della libreria sia per un \textit{capability state}, nel qual caso l'argomento
dovrà essere un dato di tipo \type{cap\_t}, che per una descrizione testuale
dello stesso,\footnote{cioè quanto ottenuto tramite la funzione
  \func{cap\_to\_text}.} nel qual caso l'argomento dovrà essere un dato di
tipo \texttt{char *}. Per questo motivo l'argomento \param{obj\_d} è
dichiarato come \texttt{void *} e deve sempre corrispondere ad un puntatore
ottenuto tramite le altre funzioni della libreria, altrimenti la funzione
fallirà con un errore di \errval{EINVAL}.

Infine si può creare una copia di un \textit{capability state} ottenuto in
precedenza tramite la funzione \funcd{cap\_dup}, il cui prototipo è:
\begin{functions}
  \headdecl{sys/capability.h}

  \funcdecl{cap\_t cap\_dup(cap\_t cap\_p)} 
  Duplica un \textit{capability state} restituendone una copia.
  
  \bodydesc{La funzione ritorna un valore non nullo in caso di successo e
    \val{NULL} in caso di errore, nel qual caso \var{errno} potrà assumere i
    valori \errval{ENOMEM} o \errval{EINVAL}.  
  }
\end{functions}

La funzione crea una copia del \textit{capability state} posto all'indirizzo
\param{cap\_p} che si è passato come argomento, restituendo il puntatore alla
copia, che conterrà gli stessi valori delle \textit{capabilities} presenti
nell'originale. La memoria necessaria viene allocata automaticamente dalla
funzione. Una volta effettuata la copia i due \textit{capability state}
potranno essere modificati in maniera completamente
indipendente.\footnote{alla fine delle operazioni si ricordi però di
  disallocare anche la copia, oltre all'originale. }

Una seconda classe di funzioni di servizio previste dall'interfaccia sono
quelle per la gestione dei dati contenuti all'interno di un \textit{capability
  state}; la prima di queste è \funcd{cap\_clear}, il cui prototipo è:
\begin{functions}
  \headdecl{sys/capability.h}

  \funcdecl{int cap\_clear(cap\_t cap\_p)} 
  Inizializza un \textit{capability state} cancellando tutte le
  \textit{capabilities}.
  
  \bodydesc{La funzione ritorna 0 in caso di successo e $-1$ in caso di
    errore, nel qual caso \var{errno} assumerà il valore \errval{EINVAL}.
  }
\end{functions}

La funzione si limita ad azzerare tutte le \textit{capabilities} presenti nel
\textit{capability state} all'indirizzo \param{cap\_p} passato come argomento,
restituendo uno stato \textsl{vuoto}, analogo a quello che si ottiene nella
creazione con \func{cap\_init}.

\begin{table}[htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|l|}
    \hline
    \textbf{Valore} & \textbf{Significato} \\
    \hline
    \hline
    \const{CAP\_EFFECTIVE}  & Capacità dell'insieme \textsl{effettivo}.\\
    \const{CAP\_PERMITTED}  & Capacità dell'insieme \textsl{permesso}.\\ 
    \const{CAP\_INHERITABLE}& Capacità dell'insieme \textsl{ereditabile}.\\
    \hline
  \end{tabular}
  \caption{Valori possibili per il tipo di dato \type{cap\_flag\_t} che
    identifica gli insiemi delle \textit{capabilities}.}
  \label{tab:cap_set_identifier}
\end{table}

Una variante di \func{cap\_clear} è \funcd{cap\_clear\_flag} che cancella da
un \textit{capability state} tutte le \textit{capabilities} di un certo
insieme fra quelli di pag.~\pageref{sec:capabilities_set}, il suo prototipo
è:
\begin{functions}
  \headdecl{sys/capability.h}

  \funcdecl{int cap\_clear\_flag(cap\_t cap\_p, cap\_flag\_t flag)} 

  Cancella dal \textit{capability state} \param{cap\_p} tutte le
  \textit{capabilities} dell'insieme \param{flag}.
  
  \bodydesc{La funzione ritorna 0 in caso di successo e $-1$ in caso di
    errore, nel qual caso \var{errno} assumerà il valore \errval{EINVAL}.  }
\end{functions}

La funzione richiede che si indichi quale degli insiemi si intente cancellare
con l'argomento \param{flag}. Questo deve essere specificato con una variabile
di tipo \type{cap\_flag\_t} che può assumere esclusivamente\footnote{si tratta
  in effetti di un tipo enumerato, come si può verificare dalla sua
  definizione che si trova in \headfile{sys/capability.h}.} uno dei valori
illustrati in tab.~\ref{tab:cap_set_identifier}.

Si possono inoltre confrontare in maniera diretta due diversi
\textit{capability state} con la funzione \funcd{cap\_compare}; il suo
prototipo è:
\begin{functions}
  \headdecl{sys/capability.h}
  \funcdecl{int cap\_compare(cap\_t cap\_a, cap\_t cap\_b)}

  Confronta due \textit{capability state}.
  
  \bodydesc{La funzione ritorna 0 se i \textit{capability state} sono identici
    ed un valore positivo se differiscono, non sono previsti errori.}
\end{functions}

La funzione esegue un confronto fra i due \textit{capability state} passati
come argomenti e ritorna in un valore intero il risultato, questo è nullo se
sono identici o positivo se vi sono delle differenze. Il valore di ritorno
della funzione consente inoltre di per ottenere ulteriori informazioni su
quali sono gli insiemi di \textit{capabilities} che risultano differenti.  Per
questo si può infatti usare la apposita macro \macro{CAP\_DIFFERS}:
\begin{functions}
  \funcdecl{int CAP\_DIFFERS(value, flag)} Controlla lo stato di eventuali
  differenze delle \textit{capabilities} nell'insieme \texttt{flag}.
\end{functions}

La macro che richiede si passi nell'argomento \texttt{value} il risultato
della funzione \func{cap\_compare} e in \texttt{flag} l'indicazione (coi
valori di tab.~\ref{tab:cap_set_identifier}) dell'insieme che si intende
controllare; restituirà un valore diverso da zero se le differenze rilevate da
\func{cap\_compare} sono presenti nell'insieme indicato.

Per la gestione dei singoli valori delle \textit{capabilities} presenti in un
\textit{capability state} l'interfaccia prevede due funzioni specifiche,
\funcd{cap\_get\_flag} e \funcd{cap\_set\_flag}, che permettono
rispettivamente di leggere o impostare il valore di una capacità all'interno
in uno dei tre insiemi già citati; i rispettivi prototipi sono:
\begin{functions}
  \headdecl{sys/capability.h}

  \funcdecl{int cap\_get\_flag(cap\_t cap\_p, cap\_value\_t cap, cap\_flag\_t
    flag, cap\_flag\_value\_t *value\_p)}
  Legge il valore di una \textit{capability}.

  \funcdecl{int cap\_set\_flag(cap\_t cap\_p, cap\_flag\_t flag, int ncap,
    cap\_value\_t *caps, cap\_flag\_value\_t value)} 
  Imposta il valore di una \textit{capability}.
  
  \bodydesc{Le funzioni ritornano 0 in caso di successo e $-1$ in caso di
    errore, nel qual caso \var{errno} assumerà il valore \errval{EINVAL}.
}
\end{functions}

In entrambe le funzioni l'argomento \param{cap\_p} indica il puntatore al
\textit{capability state} su cui operare, mentre l'argomento \param{flag}
indica su quale dei tre insiemi si intende operare, sempre con i valori di
tab.~\ref{tab:cap_set_identifier}.

La capacità che si intende controllare o impostare invece deve essere
specificata attraverso una variabile di tipo \type{cap\_value\_t}, che può
prendere come valore uno qualunque di quelli riportati in
tab.~\ref{tab:proc_capabilities}, in questo caso però non è possibile
combinare diversi valori in una maschera binaria, una variabile di tipo
\type{cap\_value\_t} può indicare una sola capacità.\footnote{in
  \headfile{sys/capability.h} il tipo \type{cap\_value\_t} è definito come
  \ctyp{int}, ma i valori validi sono soltanto quelli di
  tab.~\ref{tab:proc_capabilities}.}

Infine lo stato di una capacità è descritto ad una variabile di tipo
\type{cap\_flag\_value\_t}, che a sua volta può assumere soltanto
uno\footnote{anche questo è un tipo enumerato.} dei valori di
tab.~\ref{tab:cap_value_type}.

\begin{table}[htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|l|}
    \hline
    \textbf{Valore} & \textbf{Significato} \\
    \hline
    \hline
    \const{CAP\_CLEAR}& La capacità non è impostata.\\ 
    \const{CAP\_SET}  & La capacità è impostata.\\
    \hline
  \end{tabular}
  \caption{Valori possibili per il tipo di dato \type{cap\_flag\_value\_t} che
    indica lo stato di una capacità.}
  \label{tab:cap_value_type}
\end{table}

La funzione \func{cap\_get\_flag} legge lo stato della capacità indicata
dall'argomento \param{cap} all'interno dell'insieme indicato dall'argomento
\param{flag} lo restituisce nella variabile puntata
dall'argomento \param{value\_p}. Questa deve essere di tipo
\type{cap\_flag\_value\_t} ed assumerà uno dei valori di
tab.~\ref{tab:cap_value_type}. La funzione consente pertanto di leggere solo
lo stato di una capacità alla volta.

La funzione \func{cap\_set\_flag} può invece impostare in una sola chiamata
più \textit{capabilities}, anche se solo all'interno dello stesso insieme ed
allo stesso valore. Per questo motivo essa prende un vettore di valori di tipo
\type{cap\_value\_t} nell'argomento \param{caps}, la cui dimensione viene
specificata dall'argomento \param{ncap}. Il tipo di impostazione da eseguire
(cancellazione o impostazione) per le capacità elencate in \param{caps} viene
indicato dall'argomento \param{value} sempre con i valori di
tab.~\ref{tab:cap_value_type}.

Per semplificare la gestione delle \textit{capabilities} l'interfaccia prevede
che sia possibile utilizzare anche una rappresentazione testuale del contenuto
di un \textit{capability state} e fornisce le opportune funzioni di
gestione;\footnote{entrambe erano previste dalla bozza dello standard
  POSIX.1e.} la prima di queste, che consente di ottenere la rappresentazione
testuale, è \funcd{cap\_to\_text}, il cui prototipo è:
\begin{functions}
  \headdecl{sys/capability.h}

  \funcdecl{char * cap\_to\_text(cap\_t caps, ssize\_t * length\_p)}

  Genera una visualizzazione testuale delle \textit{capabilities}.
  
  \bodydesc{La funzione ritorna un puntatore alla stringa con la descrizione
    delle \textit{capabilities} in caso di successo e \val{NULL} in caso di
    errore, nel qual caso \var{errno} può assumere i valori \errval{EINVAL} o
    \errval{ENOMEM}.
  }
\end{functions}

La funzione ritorna l'indirizzo di una stringa contente la descrizione
testuale del contenuto del \textit{capability state} \param{caps} passato come
argomento, e, qualora l'argomento \param{length\_p} sia diverso da \val{NULL},
restituisce nella variabile intera da questo puntata la lunghezza della
stringa. La stringa restituita viene allocata automaticamente dalla funzione e
pertanto dovrà essere liberata con \func{cap\_free}.

La rappresentazione testuale, che viene usata anche di programmi di gestione a
riga di comando, prevede che lo stato venga rappresentato con una stringa di
testo composta da una serie di proposizioni separate da spazi, ciascuna delle
quali specifica una operazione da eseguire per creare lo stato finale. Nella
rappresentazione si fa sempre conto di partire da uno stato in cui tutti gli
insiemi sono vuoti e si provvede a impostarne i contenuti.

Ciascuna proposizione è nella forma di un elenco di capacità, espresso con i
nomi di tab.~\ref{tab:proc_capabilities} separati da virgole, seguito da un
operatore, e dall'indicazione degli insiemi a cui l'operazione si applica. I
nomi delle capacità possono essere scritti sia maiuscoli che minuscoli, viene
inoltre riconosciuto il nome speciale \texttt{all} che è equivalente a
scrivere la lista completa. Gli insiemi sono identificati dalle tre lettere
iniziali: ``\texttt{p}'' per il \textit{permitted}, ``\texttt{i}'' per
l'\textit{inheritable} ed ``\texttt{e}'' per l'\textit{effective} che devono
essere sempre minuscole e se ne può indicare più di uno.

Gli operatori possibili sono solo tre: ``\texttt{+}'' che aggiunge le capacità
elencate agli insiemi indicati, ``\texttt{-}'' che le toglie e ``\texttt{=}''
che le assegna esattamente. I primi due richiedono che sia sempre indicato sia
un elenco di capacità che gli insiemi a cui esse devono applicarsi, e
rispettivamente attiveranno o disattiveranno le capacità elencate nell'insieme
o negli insiemi specificati, ignorando tutto il resto. I due operatori possono
anche essere combinati nella stessa proposizione, per aggiungere e togliere le
capacità dell'elenco da insiemi diversi.

L'assegnazione si applica invece su tutti gli insiemi allo stesso tempo,
pertanto l'uso di ``\texttt{=}'' è equivalente alla cancellazione preventiva
di tutte le capacità ed alla impostazione di quelle elencate negli insiemi
specificati, questo significa che in genere lo si usa una sola volta
all'inizio della stringa. In tal caso l'elenco delle capacità può non essere
indicato e viene assunto che si stia facendo riferimento a tutte quante senza
doverlo scrivere esplicitamente.

Come esempi avremo allora che un processo non privilegiato di un utente, che
non ha nessuna capacità attiva, avrà una rappresentazione nella forma
``\texttt{=}'' che corrisponde al fatto che nessuna capacità viene assegnata a
nessun insieme (vale la cancellazione preventiva), mentre un processo con
privilegi di amministratore avrà una rappresentazione nella forma
``\texttt{=ep}'' in cui tutte le capacità vengono assegnate agli insiemi
\textit{permitted} ed \textit{effective} (e l'\textit{inheritable} è ignorato
in quanto per le regole viste a pag.~\ref{sec:capability-uid-transition} le
capacità verranno comunque attivate attraverso una \func{exec}). Infine, come
esempio meno banale dei precedenti, otterremo per \texttt{init} una
rappresentazione nella forma ``\texttt{=ep cap\_setpcap-e}'' dato che come
accennato tradizionalmente \const{CAP\_SETPCAP} è sempre stata rimossa da
detto processo.

Viceversa per passare ottenere un \textit{capability state} dalla sua
rappresentazione testuale si può usare \funcd{cap\_from\_text}, il cui
prototipo è:
\begin{functions}
  \headdecl{sys/capability.h}

  \funcdecl{cap\_t cap\_from\_text(const char *string)}

  Crea un \textit{capability state} dalla sua rappresentazione testuale.

  \bodydesc{La funzione ritorna un puntatore valido in caso di successo e
    \val{NULL} in caso di errore, nel qual caso \var{errno} può assumere i
    valori \errval{EINVAL} o \errval{ENOMEM}.}
\end{functions}

La funzione restituisce il puntatore ad un \textit{capability state}
inizializzato con i valori indicati nella stringa \param{string} che ne
contiene la rappresentazione testuale. La memoria per il \textit{capability
  state} viene allocata automaticamente dalla funzione e dovrà essere liberata
con \func{cap\_free}.

Alle due funzioni citate se ne aggiungono altre due che consentono di
convertire i valori delle costanti di tab.~\ref{tab:proc_capabilities} nelle
stringhe usate nelle rispettive rappresentazioni e viceversa. Le due funzioni,
\funcd{cap\_to\_name} e \funcd{cap\_from\_name}, sono estensioni specifiche di
Linux ed i rispettivi prototipi sono:
\begin{functions}
  \headdecl{sys/capability.h}

  \funcdecl{char * cap\_to\_name(cap\_value\_t cap)}
  \funcdecl{int cap\_from\_name(const char *name, cap\_value\_t *cap\_p)}
  Convertono le \textit{capabilities} dalle costanti alla rappresentazione
  testuale e viceversa.
  
  \bodydesc{La funzione \func{cap\_to\_name} ritorna un valore diverso da
    \val{NULL} in caso di successo e \val{NULL} in caso di errore, mentre
    \func{cap\_to\_name} ritorna rispettivamente 0 e $-1$; per entrambe in
    caso di errore \var{errno} può assumere i valori \errval{EINVAL} o
    \errval{ENOMEM}.  }
\end{functions}

La prima funzione restituisce la stringa (allocata automaticamente e che dovrà
essere liberata con \func{cap\_free}) che corrisponde al valore della
capacità \param{cap}, mentre la seconda restituisce nella variabile puntata
da \param{cap\_p} il valore della capacità rappresentata dalla
stringa \param{name}.

Fin quei abbiamo trattato solo le funzioni di servizio relative alla
manipolazione dei \textit{capability state} come strutture di dati;
l'interfaccia di gestione prevede però anche le funzioni per trattare le
\textit{capabilities} presenti nei processi. La prima di queste funzioni è
\funcd{cap\_get\_proc} che consente la lettura delle \textit{capabilities} del
processo corrente, il suo prototipo è:
\begin{functions}
  \headdecl{sys/capability.h}

  \funcdecl{cap\_t cap\_get\_proc(void)}
  Legge le \textit{capabilities} del processo corrente.
  
  \bodydesc{La funzione ritorna un valore diverso da \val{NULL} in caso di
    successo e \val{NULL} in caso di errore, nel qual caso \var{errno} può
    assumere i valori \errval{EINVAL}, \errval{EPERM} o \errval{ENOMEM}.  }
\end{functions}

La funzione legge il valore delle \textit{capabilities} associate al processo
da cui viene invocata, restituendo il risultato tramite il puntatore ad un
\textit{capability state} contenente tutti i dati che provvede ad allocare
autonomamente e che di nuovo occorrerà liberare con \func{cap\_free} quando
non sarà più utilizzato.

Se invece si vogliono leggere le \textit{capabilities} di un processo
specifico occorre usare la funzione \funcd{capgetp}, il cui
prototipo\footnote{su alcune pagine di manuale la funzione è descritta con un
  prototipo sbagliato, che prevede un valore di ritorno di tipo \type{cap\_t},
  ma il valore di ritorno è intero, come si può verificare anche dalla
  dichiarazione della stessa in \headfile{sys/capability.h}.} è:
\begin{functions}
  \headdecl{sys/capability.h}

  \funcdecl{int capgetp(pid\_t pid, cap\_t cap\_d)}
  Legge le \textit{capabilities} del processo indicato da \param{pid}.
  
  \bodydesc{La funzione ritorna 0 in caso di successo e $-1$ in caso di
    errore, nel qual caso \var{errno} può assumere i valori \errval{EINVAL},
    \errval{EPERM} o \errval{ENOMEM}.  
  }
\end{functions}
%TODO controllare e correggere i codici di errore!!!

La funzione legge il valore delle \textit{capabilities} del processo indicato
con l'argomento \param{pid}, e restituisce il risultato nel \textit{capability
  state} posto all'indirizzo indicato con l'argomento
\param{cap\_d}; a differenza della precedente in questo caso il
\textit{capability state} deve essere stato creato in precedenza. Qualora il
processo indicato non esista si avrà un errore di \errval{ESRCH}. Gli stessi
valori possono essere letti direttamente nel filesystem \textit{proc}, nei
file \texttt{/proc/<pid>/status}; ad esempio per \texttt{init} si otterrà
qualcosa del tipo:
\begin{Verbatim}
...
CapInh: 0000000000000000
CapPrm: 00000000fffffeff
CapEff: 00000000fffffeff  
...
\end{Verbatim}

Infine per impostare le \textit{capabilities} del processo corrente (non
esiste una funzione che permetta di cambiare le \textit{capabilities} di un
altro processo) si deve usare la funzione \funcd{cap\_set\_proc}, il cui
prototipo è:
\begin{functions}
  \headdecl{sys/capability.h}

  \funcdecl{int cap\_set\_proc(cap\_t cap\_p)}
  Imposta le \textit{capabilities} del processo corrente.
  
  \bodydesc{La funzione ritorna 0 in caso di successo e $-1$ in caso di
    errore, nel qual caso \var{errno} può assumere i valori \errval{EINVAL},
    \errval{EPERM} o \errval{ENOMEM}.  
  }
\end{functions}

La funzione modifica le \textit{capabilities} del processo corrente secondo
quanto specificato con l'argomento \param{cap\_p}, posto che questo sia
possibile nei termini spiegati in precedenza (non sarà ad esempio possibile
impostare capacità non presenti nell'insieme di quelle permesse). In caso di
successo i nuovi valori saranno effettivi al ritorno della funzione, in caso
di fallimento invece lo stato delle capacità resterà invariato. Si tenga
presente che \textsl{tutte} le capacità specificate tramite \param{cap\_p}
devono essere permesse; se anche una sola non lo è la funzione fallirà, e per
quanto appena detto, lo stato delle \textit{capabilities} non verrà modificato
(neanche per le parti eventualmente permesse).

Come esempio di utilizzo di queste funzioni nei sorgenti allegati alla guida
si è distribuito il programma \texttt{getcap.c}, che consente di leggere le
\textit{capabilities} del processo corrente\footnote{vale a dire di sé stesso,
  quando lo si lancia, il che può sembrare inutile, ma serve a mostrarci quali
  sono le \textit{capabilities} standard che ottiene un processo lanciato
  dalla riga di comando.} o tramite l'opzione \texttt{-p}, quelle di un
processo qualunque il cui pid viene passato come parametro dell'opzione.

\begin{figure}[!htbp]
  \footnotesize \centering
  \begin{minipage}[c]{\codesamplewidth}
    \includecodesample{listati/getcap.c}
  \end{minipage} 
  \normalsize
  \caption{Corpo principale del programma \texttt{getcap.c}.}
  \label{fig:proc_getcap}
\end{figure}

La sezione principale del programma è riportata in fig.~\ref{fig:proc_getcap},
e si basa su una condizione sulla variabile \var{pid} che se si è usato
l'opzione \texttt{-p} è impostata (nella sezione di gestione delle opzioni,
che si è tralasciata) al valore del \textsl{pid} del processo di cui si vuole
leggere le \textit{capabilities} e nulla altrimenti. Nel primo caso
(\texttt{\small 1--6}) si utilizza direttamente (\texttt{\small 2})
\func{cap\_get\_proc} per ottenere lo stato delle capacità del processo, nel
secondo (\texttt{\small 7--14}) prima si inizializza (\texttt{\small 8}) uno
stato vuoto e poi (\texttt{\small 9}) si legge il valore delle capacità del
processo indicato.

Il passo successivo è utilizzare (\texttt{\small 16}) \func{cap\_to\_text} per
tradurre in una stringa lo stato, e poi (\texttt{\small 17}) stamparlo; infine
(\texttt{\small 19--20}) si libera la memoria allocata dalle precedenti
funzioni con \func{cap\_free} per poi ritornare dal ciclo principale della
funzione.

\itindend{capabilities}

% TODO vedi http://lwn.net/Articles/198557/ e 
% http://www.madore.org/~david/linux/newcaps/



\subsection{La gestione dei {chroot}}
\label{sec:file_chroot}

% TODO introdurre nuova sezione sulle funzionalità di sicurezza avanzate, con
% dentro chroot SELinux e AppArmor, Tomoyo, Smack, cgroup o che altro ???

% inserire setns (introdotta con il 3.0, vedi http://lwn.net/Articles/407495/)
% e le funzionalità di isolamento dei container

Benché non abbia niente a che fare con permessi, utenti e gruppi, la funzione
\func{chroot} viene usata spesso per restringere le capacità di accesso di un
programma ad una sezione limitata del filesystem, per cui ne parleremo in
questa sezione.

% TODO riferimenti ai bind mount, link simbolici ecc.

Come accennato in sez.~\ref{sec:proc_fork} ogni processo oltre ad una
\index{directory~di~lavoro} directory di lavoro, ha anche una directory
\textsl{radice}\footnote{entrambe sono contenute in due campi (rispettivamente
  \var{pwd} e \var{root}) di \kstruct{fs\_struct}; vedi
  fig.~\ref{fig:proc_task_struct}.} che, pur essendo di norma corrispondente
alla radice dell'albero di file e directory come visto dal kernel (ed
illustrato in sez.~\ref{sec:file_pathname}), ha per il processo il significato
specifico di directory rispetto alla quale vengono risolti i
\itindsub{pathname}{assoluto}\textit{pathname} assoluti.\footnote{cioè quando
  un processo chiede la risoluzione di un \textit{pathname}, il kernel usa
  sempre questa directory come punto di partenza.} Il fatto che questo valore
sia specificato per ogni processo apre allora la possibilità di modificare le
modalità di risoluzione dei \textit{pathname} assoluti da parte di un processo
cambiando questa directory, così come si fa coi
\itindsub{pathname}{relativo}\textit{pathname} relativi cambiando la
\index{directory~di~lavoro} directory di lavoro.

Normalmente la directory radice di un processo coincide anche con la radice
del filesystem usata dal kernel, e dato che il suo valore viene ereditato dal
padre da ogni processo figlio, in generale i processi risolvono i
\itindsub{pathname}{assoluto} \textit{pathname} assoluti a partire sempre
dalla stessa directory, che corrisponde alla radice del sistema.

In certe situazioni però è utile poter impedire che un processo possa accedere
a tutto il filesystem; per far questo si può cambiare la sua directory radice
con la funzione \funcd{chroot}, il cui prototipo è:
\begin{prototype}{unistd.h}{int chroot(const char *path)}
  Cambia la directory radice del processo a quella specificata da
  \param{path}.
  
\bodydesc{La funzione restituisce zero in caso di successo e -1 per
    un errore, in caso di errore \var{errno} può assumere i valori:
  \begin{errlist}
  \item[\errcode{EPERM}] l'\ids{UID} effettivo del processo non è zero.
  \end{errlist}
  ed inoltre \errval{EFAULT}, \errval{ENAMETOOLONG}, \errval{ENOENT},
  \errval{ENOMEM}, \errval{ENOTDIR}, \errval{EACCES}, \errval{ELOOP};
  \errval{EROFS} e \errval{EIO}.}
\end{prototype}
\noindent in questo modo la directory radice del processo diventerà
\param{path} (che ovviamente deve esistere) ed ogni
\itindsub{pathname}{assoluto}\textit{pathname} assoluto usato dalle funzioni
chiamate nel processo sarà risolto a partire da essa, rendendo impossibile
accedere alla parte di albero sovrastante.  Si ha così quella che viene
chiamata una \textit{chroot jail}, in quanto il processo non può più accedere
a file al di fuori della sezione di albero in cui è stato
\textsl{imprigionato}. 

Solo un processo con i privilegi di amministratore può usare questa funzione,
e la nuova radice, per quanto detto in sez.~\ref{sec:proc_fork}, sarà ereditata
da tutti i suoi processi figli. Si tenga presente però che la funzione non
cambia la directory di lavoro, che potrebbe restare fuori dalla \textit{chroot
  jail}.

Questo è il motivo per cui la funzione è efficace solo se dopo averla eseguita
si cedono i privilegi di root. Infatti se per un qualche motivo il processo
resta con \index{directory~di~lavoro} la directory di lavoro fuori dalla
\textit{chroot jail}, potrà comunque accedere a tutto il resto del filesystem
usando \itindsub{pathname}{relativo}\textit{pathname} relativi, i quali,
partendo dalla directory di lavoro che è fuori della \textit{chroot jail},
potranno (con l'uso di ``\texttt{..}'') risalire fino alla radice effettiva
del filesystem.

Ma se ad un processo restano i privilegi di amministratore esso potrà comunque
portare la sua \index{directory~di~lavoro} directory di lavoro fuori dalla
\textit{chroot jail} in cui si trova. Basta infatti creare una nuova
\textit{chroot jail} con l'uso di \func{chroot} su una qualunque directory
contenuta nell'attuale directory di lavoro.  Per questo motivo l'uso di questa
funzione non ha molto senso quando un processo necessita dei privilegi di root
per le sue normali operazioni.

Un caso tipico di uso di \func{chroot} è quello di un server FTP anonimo, in
questo caso infatti si vuole che il server veda solo i file che deve
trasferire, per cui in genere si esegue una \func{chroot} sulla directory che
contiene i file.  Si tenga presente però che in questo caso occorrerà
replicare all'interno della \textit{chroot jail} tutti i file (in genere
programmi e librerie) di cui il server potrebbe avere bisogno.



% TODO: trattare la funzione setns e i namespace file descriptors (vedi
% http://lwn.net/Articles/407495/) introdotti con il kernel 3.0

% TODO: spostare chroot e le funzioni affini relative ai container da qualche
% parte diversa se è il caso. 

% LocalWords:  sez like filesystem unlink MacOS Windows VMS inode kernel unistd
% LocalWords:  int const char oldpath newpath errno EXDEV EPERM st Smack SysV
% LocalWords:  EEXIST EMLINK EACCES ENAMETOOLONG ENOTDIR EFAULT ENOMEM EROFS ls
% LocalWords:  ELOOP ENOSPC EIO pathname nlink stat vfat fsck EISDIR ENOENT cap
% LocalWords:  POSIX socket fifo sticky root system call count crash init linux
% LocalWords:  descriptor remove rename rmdir stdio glibc libc NFS DT obj dup
% LocalWords:  ENOTEMPTY EBUSY mount point EINVAL soft symbolic tab symlink fig
% LocalWords:  dangling access chdir chmod chown creat exec lchown lstat mkdir
% LocalWords:  mkfifo mknod opendir pathconf readlink truncate path buff size
% LocalWords:  grub bootloader grep MAXSYMLINKS cat VFS sys dirname fcntl tv Py
% LocalWords:  dev umask IFREG IFBLK IFCHR IFIFO SVr sgid BSD SVID NULL from to
% LocalWords:  stream dirent EMFILE ENFILE dirfd SOURCE fchdir readdir struct
% LocalWords:  EBADF namlen HAVE thread entry result value argument fileno ext
% LocalWords:  name TYPE OFF RECLEN UNKNOWN REG SOCK CHR BLK type IFTODT DTTOIF
% LocalWords:  DTYPE off reclen seekdir telldir void rewinddir closedir select
% LocalWords:  namelist compar malloc qsort alphasort versionsort strcoll myls
% LocalWords:  strcmp direntry while current working home shell pwd get stddef
% LocalWords:  getcwd ERANGE getwd change fd race condition tmpnam getfacl mark
% LocalWords:  string tmpdir TMP tempnam pfx TMPNAME suid tmp EXCL tmpfile pid
% LocalWords:  EINTR mktemp mkstemp stlib template filename XXXXXX OpenBSD buf
% LocalWords:  mkdtemp fstat filedes nell'header padding ISREG ISDIR ISCHR IFMT
% LocalWords:  ISBLK ISFIFO ISLNK ISSOCK IFSOCK IFLNK IFDIR ISUID UID ISGID GID
% LocalWords:  ISVTX IRUSR IWUSR IXUSR IRGRP IWGRP IXGRP IROTH IWOTH IXOTH  OLD
% LocalWords:  blocks blksize holes lseek TRUNC ftruncate ETXTBSY length QCMD
% LocalWords:  hole atime read utime mtime write ctime modification leafnode cp
% LocalWords:  make fchmod fchown utimbuf times actime modtime Mac owner uid fs
% LocalWords:  gid Control List patch mandatory control execute group other all
% LocalWords:  effective passwd IGID locking swap saved text IRWXU IRWXG subcmd
% LocalWords:  IRWXO capability FSETID mask capabilities chroot jail QUOTAOFF
% LocalWords:  FTP filter Attributes Solaris FreeBSD libacl hash at dqblk SYNC
% LocalWords:  XFS SELinux namespace attribute security trusted Draft Modules
% LocalWords:  attributes mime ADMIN FOWNER libattr lattr getxattr lgetxattr of
% LocalWords:  fgetxattr attr ssize ENOATTR ENOTSUP NUL setxattr lsetxattr list
% LocalWords:  fsetxattr flags XATTR REPLACE listxattr llistxattr flistxattr by
% LocalWords:  removexattr lremovexattr fremovexattr attributename acl GETINFO
% LocalWords:  OBJ setfacl len any prefix separator options NUMERIC IDS SMART
% LocalWords:  INDENT major number IDE Documentation makedev proc copy LNK long
% LocalWords:  euidaccess eaccess delete def tag qualifier permset calendar NOW
% LocalWords:  mutt noatime relatime strictatime atim nsec mtim ctim atimensec
% LocalWords:  mtimensec utimes timeval futimes lutimes ENOSYS futimens OMIT PR
% LocalWords:  utimensat timespec sec futimesat LIDS DAC OVERRIDE SEARCH chattr
% LocalWords:  Discrectionary KILL SETGID domain SETUID setuid setreuid SETPCAP
% LocalWords:  setresuid setfsuid IMMUTABLE immutable append only BIND SERVICE
% LocalWords:  BROADCAST broadcast multicast multicasting RAW PACKET IPC LOCK
% LocalWords:  memory mlock mlockall shmctl mmap MODULE RAWIO ioperm iopl PACCT
% LocalWords:  ptrace accounting NICE RESOURCE TTY CONFIG hangup vhangup dell'
% LocalWords:  LEASE lease SETFCAP AUDIT permitted inherited inheritable AND nn
% LocalWords:  bounding execve fork capget capset header hdrp datap ESRCH undef
% LocalWords:  version libcap lcap clear ncap caps pag capgetp CapInh CapPrm RT
% LocalWords:  fffffeff CapEff getcap scheduling lookup  dqinfo SETINFO GETFMT
% LocalWords:  NEWNS unshare nice NUMA ioctl journaling close XOPEN fdopendir
% LocalWords:  btrfs mkostemp extN ReiserFS JFS Posix usrquota grpquota EDQUOT
% LocalWords:  aquota quotacheck limit grace period quotactl cmd caddr addr dqb
% LocalWords:  QUOTAON ENODEV ENOPKG ENOTBLK GETQUOTA SETQUOTA SETUSE SETQLIM
% LocalWords:  forced allowed sendmail SYSLOG WAKE ALARM CLOCK BOOTTIME dqstats
% LocalWords:  REALTIME securebits GETSTATS QFMT curspace curinodes btime itime
% LocalWords:  QIF BLIMITS bhardlimit bsoftlimit ILIMITS ihardlimit isoftlimit
% LocalWords:  INODES LIMITS USAGE valid dqi IIF BGRACE bgrace IGRACE igrace is
% LocalWords:  Python Truelite Srl quotamodule Repository who nell' dall' KEEP
% LocalWords:  SECURE KEEPCAPS prctl FIXUP NOROOT LOCKED dell'IPC dell'I IOPRIO
% LocalWords:  CAPBSET CLASS IDLE dcookie overflow DIFFERS Virtual everything
% LocalWords:  dentry register resolution cache dcache operation llseek poll ln
% LocalWords:  multiplexing fsync fasync seek block superblock gapil tex img du
% LocalWords:  second linked journaled source filesystemtype unsigned device
% 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 such offsetof
% LocalWords:  member scan attack EOVERFLOW BITS blkcnt rdev

%%% Local Variables: 
%%% mode: latex
%%% TeX-master: "gapil"
%%% End: 
