%% filedir.tex
%%
%% Copyright (C) 2000-2011 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}

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}

% 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:file_link}).\\
    \textsl{\code{unlink}} & Cancella un \textit{hard link} (vedi
                             sez.~\ref{sec:file_link}).\\
    \textsl{\code{symlink}}& Crea un link simbolico (vedi
                             sez.~\ref{sec:file_symlink}).\\
    \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 file speciale (vedi
                             sez.~\ref{sec:file_mknod}).\\
    \textsl{\code{rename}} & Cambia il nome di un file (vedi
                             sez.~\ref{sec:file_remove}).\\
    \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 \func{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
\struct{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 \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 \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:file_link}), ed in realtà non cancella
  affatto i dati del file, ma si limita ad eliminare la relativa voce da una
  directory e decrementare il numero di riferimenti nell'\textit{inode}.
  
\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:file_link}) a file nel filesystem corrente.
  
\item Quando si cambia nome ad un file senza cambiare filesystem il contenuto
  del file non viene spostato fisicamente, viene semplicemente creata una
  nuova voce per l'\textit{inode} in questione e rimossa la precedente, questa
  è la modalità in cui opera normalmente il comando \cmd{mv} attraverso la
  funzione \func{rename} (vedi sez.~\ref{sec:file_remove}). Questa operazione
  non modifica minimamente neanche l'\textit{inode} del file, dato che non si
  opera sul file ma sulla directory che lo contiene.

\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 \acr{ext3}, probabilmente ancora il filesystem più
diffuso, ed una serie di ulteriori miglioramento 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 \acr{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 link 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 \textit{superblock} sono quindi ridondati) per una maggiore
affidabilità e possibilità di recupero in caso di corruzione del
\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} 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 inode \itindex{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 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)


\subsection{La gestione dell'uso dei filesystem}
\label{sec:sys_file_config}

Come accennato in sez.~\ref{sec:file_arch_overview} per poter accedere ai file
occorre prima rendere disponibile al sistema il filesystem su cui essi sono
memorizzati; l'operazione di attivazione del filesystem è chiamata
\textsl{montaggio}, per far questo in Linux si usa la funzione \funcd{mount},
il cui prototipo è:\footnote{la funzione è una versione specifica di Linux che
  usa la omonima \textit{system call} e non è portabile.}

\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 \itindex{pathname} \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
    \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{EMFILE}] la tabella dei device \textit{dummy} è 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{ELOOP}, \errval{ENOMEM},
  \errval{ENAMETOOLONG}, \errval{ENOENT}, \errval{ENOTDIR} nel loro
  significato generico.}
\end{funcproto}

La funzione monta sulla directory indicata \param{target}, detta
\itindex{mount~point} \textit{mount point}, il filesystem contenuto nel file
di dispositivo indicato \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 \itindex{pathname}
\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 \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
opzioni del filesystem che devono essere impostate, in sostanza viene usato 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.

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.

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 in diversi \itindex{mount~point} \textit{mount point} lo stesso
filesystem, sia montare più filesystem sullo stesso \itindex{mount~point}
\textit{mount point}, nel qual caso vale quanto appena detto, e solo il
contenuto dell'ultimo filesystem montato sarà visibile.

Ciascun filesystem è dotato di caratteristiche specifiche che possono essere
attivate o meno, alcune di queste sono generali (anche se non è detto siano
disponibili in ogni filesystem), e vengono specificate come opzioni di
montaggio con l'argomento \param{mountflags}.  

In Linux \param{mountflags} deve essere un intero a 32 bit i cui 16 più
significativi sono un \itindex{magic~number} \textit{magic
  number}\footnote{che nel caso è \code{0xC0ED}, si può usare la costante
  \const{MS\_MGC\_MSK} per ottenere la parte di \param{mountflags} riservata
  al \textit{magic number}.} mentre i 16 meno significativi sono usati per
specificare le opzioni; essi sono usati come maschera binaria e vanno
impostati con un OR aritmetico della costante \const{MS\_MGC\_VAL} con i
valori riportati in tab.~\ref{tab:sys_mount_flags}.

\begin{table}[htb]
  \footnotesize
  \centering
  \begin{tabular}[c]{|l|p{8cm}|}
    \hline
    \textbf{Parametro} & \textbf{Significato}\\
    \hline
    \hline
    \const{MS\_BIND}       & Monta il filesystem altrove.\\
    \const{MS\_DIRSYNC}    & .\\
    \const{MS\_MANDLOCK}   & Consente il \textit{mandatory locking} 
                             \itindex{mandatory~locking} (vedi
                             sez.~\ref{sec:file_mand_locking}).\\
    \const{MS\_MOVE}       & Sposta atomicamente il punto di montaggio.\\
    \const{MS\_NOATIME}    & Non aggiorna gli \textit{access time} (vedi
                             sez.~\ref{sec:file_file_times}).\\
    \const{MS\_NODEV}      & Impedisce l'accesso ai file di dispositivo.\\
    \const{MS\_NODIRATIME} & Non aggiorna gli \textit{access time} delle
                             directory.\\
    \const{MS\_NOEXEC}     & Impedisce di eseguire programmi.\\
    \const{MS\_NOSUID}     & Ignora i bit \itindex{suid~bit} \acr{suid} e
                             \itindex{sgid~bit} \acr{sgid}.\\ 
    \const{MS\_RDONLY}     & Monta in sola lettura.\\
    \const{MS\_RELATIME}   & .\\
    \const{MS\_REMOUNT}    & Rimonta il filesystem cambiando le opzioni.\\
    \const{MS\_SILENT}     & .\\
    \const{MS\_STRICTATIME}& .\\
    \const{MS\_SYNCHRONOUS}& Abilita la scrittura sincrona.\\
    % \const{S\_WRITE}       &  Scrive normalmente.\\
    % \const{S\_APPEND}      &  Consente la scrittura solo in
    %                          \itindex{append~mode} \textit{append mode} 
    %                          (vedi sez.~\ref{sec:file_sharing}).\\
    % \const{S\_IMMUTABLE}   &  Impedisce che si possano modificare i file.\\
    \hline
  \end{tabular}
  \caption{Tabella dei codici dei flag di montaggio di un filesystem.}
  \label{tab:sys_mount_flags}
\end{table}

% TODO aggiornare con i nuovi flag di man mount
% verificare i readonly mount bind del 2.6.26

La funzione \func{mount} può essere utilizzata anche per effettuare il
\textsl{rimontaggio} di un filesystem, cosa che permette di cambiarne al volo
alcune delle caratteristiche di funzionamento (ad esempio passare da sola
lettura a lettura/scrittura). Questa operazione è attivata attraverso uno dei
bit di \param{mountflags}, \const{MS\_REMOUNT}, che se impostato specifica che
deve essere effettuato il rimontaggio del filesystem (con le opzioni
specificate dagli altri bit), anche in questo caso il valore di \param{source}
viene ignorato.

Una volta che non si voglia più utilizzare un certo filesystem è possibile
\textsl{smontarlo} usando la funzione \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{EPERM}] il processo non ha i privilegi di amministratore.
  \item[\errcode{EBUSY}]  \param{target} è la directory di lavoro di qualche
  processo, o contiene dei file aperti, o un altro mount point.
\end{errlist}ed inoltre \errval{ENOTDIR}, \errval{EFAULT}, \errval{ENOMEM},
\errval{ENAMETOOLONG}, \errval{ENOENT}, \errval{ELOOP} nel loro
  significato generico.}
\end{funcproto}

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 con il kernel 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 quando il filesystem è
\textsl{occupato}, questo avviene quando ci sono ancora file aperti sul
filesystem, se questo contiene la directory di lavoro corrente di un qualunque
processo o il \itindex{mount~point} \textit{mount point} di un altro
filesystem; in questo caso l'errore restituito è \errcode{EBUSY}.

Linux provvede inoltre una seconda funzione, \funcd{umount2}, che in alcuni
casi permette di 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 è identica a \func{umount} per valori di ritorno e codici di
  errore. }
\end{funcproto}

Il valore di \param{flags} è una maschera binaria, e al momento l'unico valore
definito è il bit \const{MNT\_FORCE}; gli altri bit devono essere nulli.
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. 

% TODO documentare MNT_DETACH e MNT_EXPIRE ...

Altre due funzioni specifiche di Linux,\footnote{esse si trovano anche su BSD,
  ma con una struttura diversa.} utili per ottenere in maniera diretta
informazioni riguardo al filesystem su cui si trova un certo file, sono
\funcd{statfs} e \funcd{fstatfs}, i cui prototipi sono:

\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
  \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; queste 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}


Le \acr{glibc} provvedono infine una serie di funzioni per la gestione dei due
file \conffile{/etc/fstab} ed \conffile{/etc/mtab}, 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, per
\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}, per cui ne
tralasceremo la trattazione, rimandando al manuale delle \acr{glibc}
\cite{glibc} per la documentazione completa.

% TODO scrivere relativamente alle varie funzioni (getfsent e getmntent &C)
% TODO documentare swapon e swapoff (man 2 ...)





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

Come già accennato in sez.~\ref{sec:file_filesystem} in un sistema unix-like
la gestione dei file ha delle caratteristiche specifiche che derivano
direttamente dall'architettura del sistema.  In questa sezione esamineremo le
funzioni usate per la manipolazione di file e directory, per la creazione di
link simbolici e diretti, per la gestione e la lettura delle directory.

In particolare ci soffermeremo sulle conseguenze che derivano
dall'architettura dei filesystem illustrata nel capitolo precedente per quanto
riguarda il comportamento e gli effetti delle varie funzioni.


\subsection{Le funzioni \func{link} e \func{unlink}}
\label{sec:file_link}

Una caratteristica comune a diversi sistemi operativi è quella di poter creare
dei nomi fittizi (come gli alias del vecchio MacOS o i collegamenti di Windows
o i nomi logici del VMS) che permettono di fare riferimento allo stesso file
chiamandolo con nomi diversi o accedendovi da directory diverse.

Questo è possibile anche in ambiente Unix, dove tali collegamenti sono
usualmente chiamati \textit{link}; ma data l'architettura del sistema riguardo
la gestione dei file ci sono due metodi sostanzialmente diversi per fare
questa operazione.

Come spiegato in sez.~\ref{sec:file_filesystem} l'accesso al contenuto di un
file su disco avviene passando attraverso il suo \itindex{inode}
\textit{inode}, che è la struttura usata dal kernel che lo identifica
univocamente all'interno di un singolo filesystem. Il nome del file che si
trova nella voce di una directory è solo un'etichetta, mantenuta all'interno
della directory, che viene associata ad un puntatore che fa riferimento al
suddetto \textit{inode}.

Questo significa che, fintanto che si resta sullo stesso filesystem, la
realizzazione di un link è immediata, ed uno stesso file può avere tanti nomi
diversi, dati da altrettante associazioni diverse allo stesso \itindex{inode}
\textit{inode} effettuate tramite ``etichette'' diverse in directory
diverse. Si noti anche che nessuno di questi nomi viene ad assumere una
particolare preferenza o originalità rispetto agli altri, in quanto tutti
fanno comunque riferimento allo stesso \itindex{inode} \textit{inode}.

Per aggiungere ad una directory una voce che faccia riferimento ad un
\itindex{inode} \textit{inode} già esistente si utilizza la funzione
\func{link}; si suole chiamare questo tipo di associazione un collegamento
diretto, o \textit{hard link}.  Il prototipo della funzione è il seguente:
\begin{prototype}{unistd.h}
{int link(const char *oldpath, const char *newpath)}
  Crea un nuovo collegamento diretto.
  
  \bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di
    errore nel qual caso \var{errno} viene impostata ai valori:
  \begin{errlist}
  \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}.
  \item[\errcode{EPERM}] il filesystem che contiene \param{oldpath} e
    \param{newpath} non supporta i link diretti o è una directory.
  \item[\errcode{EEXIST}] un file (o una directory) di nome \param{newpath}
    esiste già.
  \item[\errcode{EMLINK}] ci sono troppi link al file \param{oldpath} (il
    numero massimo è specificato dalla variabile \const{LINK\_MAX}, vedi
    sez.~\ref{sec:sys_limits}).
  \end{errlist}
  ed inoltre \errval{EACCES}, \errval{ENAMETOOLONG}, \errval{ENOTDIR},
  \errval{EFAULT}, \errval{ENOMEM}, \errval{EROFS}, \errval{ELOOP},
  \errval{ENOSPC}, \errval{EIO}.}
\end{prototype}

La funzione crea sul \itindex{pathname} \textit{pathname} \param{newpath} un
collegamento diretto al file indicato da \param{oldpath}.  Per quanto detto la
creazione di un nuovo collegamento diretto non copia il contenuto del file, ma
si limita a creare una voce nella directory specificata da \param{newpath} e
ad aumentare di uno il numero di riferimenti al file (riportato nel campo
\var{st\_nlink} della struttura \struct{stat}, vedi sez.~\ref{sec:file_stat})
aggiungendo il nuovo nome ai precedenti. Si noti che uno stesso file può
essere così chiamato con vari nomi in diverse directory.

Per quanto dicevamo in sez.~\ref{sec:file_filesystem} la creazione di un
collegamento diretto è possibile solo se entrambi i \itindex{pathname}
\textit{pathname} sono nello stesso filesystem; inoltre il filesystem deve
supportare i collegamenti diretti (il meccanismo non è disponibile ad esempio
con il filesystem \acr{vfat} di Windows). In realtà la funzione ha un
ulteriore requisito, e cioè che non solo che i due file siano sullo stesso
filesystem, ma anche che si faccia riferimento ad essi sullo stesso
\itindex{mount~point} \textit{mount point}.\footnote{si tenga presente infatti
  (vedi sez.~\ref{sec:sys_file_config}) che a partire dal kernel 2.4 uno
  stesso filesystem può essere montato più volte su directory diverse.}

La funzione inoltre opera sia sui file ordinari che sugli altri oggetti del
filesystem, con l'eccezione delle directory. In alcune versioni di Unix solo
l'amministratore è in grado di creare un collegamento diretto ad un'altra
directory: questo viene fatto perché con una tale operazione è possibile
creare dei \textit{loop} nel filesystem (vedi l'esempio mostrato in
sez.~\ref{sec:file_symlink}, dove riprenderemo il discorso) che molti programmi
non sono in grado di gestire e la cui rimozione diventerebbe estremamente
complicata (in genere per questo tipo di errori occorre far girare il
programma \cmd{fsck} per riparare il filesystem).

Data la pericolosità di questa operazione e la disponibilità dei link
simbolici che possono fornire la stessa funzionalità senza questi problemi,
nel caso di Linux questa capacità è stata completamente disabilitata, e al
tentativo di creare un link diretto ad una directory la funzione \func{link}
restituisce l'errore \errcode{EPERM}.

Un ulteriore comportamento peculiare di Linux è quello in cui si crea un
\textit{hard link} ad un link simbolico. In questo caso lo standard POSIX
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
  \href{http://lwn.net/Articles/293902}
  {\texttt{http://lwn.net/Articles/293902}}).} è stato adottato un
comportamento che non segue più lo standard per cui l'\textit{hard link} viene
creato rispetto al link simbolico, e non al file cui questo punta.

La ragione di questa differenza rispetto allo standard, presente anche in
altri sistemi unix-like, sono dovute al fatto che un link simbolico può fare
riferimento anche ad un file non esistente o a una directory, per i quali
l'\textit{hard link} non può essere creato, per cui la scelta di seguire il
link simbolico è stata ritenuta una scelta scorretta nella progettazione
dell'interfaccia.  Infatti se non ci fosse il comportamento adottato da Linux
sarebbe impossibile creare un \textit{hard link} ad un link simbolico, perché
la funzione lo risolverebbe e l'\textit{hard link} verrebbe creato verso la
destinazione. Invece evitando di seguire lo standard l'operazione diventa
possibile, ed anche il comportamento della funzione risulta molto più
comprensibile. Tanto più che se proprio se si vuole creare un \textit{hard
  link} rispetto alla destinazione di un link simbolico è sempre possibile
farlo direttamente.\footnote{ciò non toglie che questo comportamento fuori
  standard possa causare problemi, come nell'esempio descritto nell'articolo
  citato nella nota precedente, a programmi che non si aspettano questa
  differenza rispetto allo standard POSIX.}

La rimozione di un file (o più precisamente della voce che lo referenzia
all'interno di una directory) si effettua con la funzione \funcd{unlink}; il
suo prototipo è il seguente:
\begin{prototype}{unistd.h}{int unlink(const char *pathname)}

  Cancella un file.
  
  \bodydesc{La funzione restituisce zero in caso di successo e -1 per un
    errore, nel qual caso il file non viene toccato. La variabile
    \var{errno} viene impostata secondo i seguenti codici di errore:
  \begin{errlist}
  \item[\errcode{EISDIR}] \param{pathname} si riferisce ad una directory.
    \footnotemark
  \item[\errcode{EROFS}] \param{pathname} è su un filesystem montato in sola
  lettura.
  \item[\errcode{EISDIR}] \param{pathname} fa riferimento a una directory.
  \end{errlist}
  ed inoltre: \errval{EACCES}, \errval{EFAULT}, \errval{ENOENT},
  \errval{ENOTDIR}, \errval{ENOMEM}, \errval{EROFS}, \errval{ELOOP},
  \errval{EIO}.}
\end{prototype}

\footnotetext{questo è un valore specifico ritornato da Linux che non consente
  l'uso di \func{unlink} con le directory (vedi sez.~\ref{sec:file_remove}).
  Non è conforme allo standard POSIX, che prescrive invece l'uso di
  \errcode{EPERM} in caso l'operazione non sia consentita o il processo non
  abbia privilegi sufficienti.}

La funzione cancella il nome specificato da \param{pathname} nella relativa
directory e decrementa il numero di riferimenti nel relativo \itindex{inode}
\textit{inode}. Nel caso di link simbolico cancella il link simbolico; nel
caso di socket, fifo o file di dispositivo \index{file!di~dispositivo} rimuove
il nome, ma come per i file i processi che hanno aperto uno di questi oggetti
possono continuare ad utilizzarlo.

Per cancellare una voce in una directory è necessario avere il permesso di
scrittura su di essa, dato che si va a rimuovere una voce dal suo contenuto, e
il diritto di esecuzione sulla directory che la contiene (affronteremo in
dettaglio l'argomento dei permessi di file e directory in
sez.~\ref{sec:file_access_control}). Se inoltre lo \itindex{sticky~bit}
\textit{sticky bit} (vedi sez.~\ref{sec:file_special_perm}) è impostato
occorrerà anche essere proprietari del file o proprietari della directory (o
root, per cui nessuna delle restrizioni è applicata).

Una delle caratteristiche di queste funzioni è che la creazione/rimozione del
nome dalla directory e l'incremento/decremento del numero di riferimenti
\itindex{inode} nell'\textit{inode} devono essere effettuati in maniera
atomica (si veda sez.~\ref{sec:proc_atom_oper}) senza possibili interruzioni
fra le due operazioni. Per questo entrambe queste funzioni sono realizzate
tramite una singola system call.

Si ricordi infine che un file non viene eliminato dal disco fintanto che tutti
i riferimenti ad esso sono stati cancellati: solo quando il \textit{link
  count} mantenuto \itindex{inode} nell'\textit{inode} diventa zero lo spazio
occupato su disco viene rimosso (si ricordi comunque che a questo si aggiunge
sempre un'ulteriore condizione,\footnote{come vedremo in
  cap.~\ref{cha:file_unix_interface} il kernel mantiene anche una tabella dei
  file aperti nei vari processi, che a sua volta contiene i riferimenti agli
  \itindex{inode} \textit{inode} ad essi relativi. Prima di procedere alla
  cancellazione dello spazio occupato su disco dal contenuto di un file il
  kernel controlla anche questa tabella, per verificare che anche in essa non
  ci sia più nessun riferimento all'\textit{inode} in questione.} e cioè che
non ci siano processi che abbiano il suddetto file aperto).

Questa proprietà viene spesso usata per essere sicuri di non lasciare file
temporanei su disco in caso di crash dei programmi; la tecnica è quella di
aprire il file e chiamare \func{unlink} subito dopo, in questo modo il
contenuto del file è sempre disponibile all'interno del processo attraverso il
suo file descriptor (vedi sez.~\ref{sec:file_fd}) fintanto che il processo non
chiude il file, ma non ne resta traccia in nessuna directory, e lo spazio
occupato su disco viene immediatamente rilasciato alla conclusione del
processo (quando tutti i file vengono chiusi).


\subsection{Le funzioni \func{remove} e \func{rename}}
\label{sec:file_remove}

Al contrario di quanto avviene con altri Unix, in Linux non è possibile usare
\func{unlink} sulle directory; per cancellare una directory si può usare la
funzione \func{rmdir} (vedi sez.~\ref{sec:file_dir_creat_rem}), oppure la
funzione \funcd{remove}. 

Questa è la funzione prevista dallo standard ANSI C per cancellare un file o
una directory (e funziona anche per i sistemi che non supportano i link
diretti). Per i file è identica a \func{unlink} e per le directory è identica
a \func{rmdir}; il suo prototipo è:
\begin{prototype}{stdio.h}{int remove(const char *pathname)}
  Cancella un nome dal filesystem. 
  
  \bodydesc{La funzione restituisce zero in caso di successo e -1 per un
    errore, nel qual caso il file non viene toccato.
    
    I codici di errore riportati in \var{errno} sono quelli della chiamata
    utilizzata, pertanto si può fare riferimento a quanto illustrato nelle
    descrizioni di \func{unlink} e \func{rmdir}.}
\end{prototype}

La funzione utilizza la funzione \func{unlink}\footnote{questo vale usando le
  \acr{glibc}; nelle libc4 e nelle libc5 la funzione \func{remove} è un
  semplice alias alla funzione \func{unlink} e quindi non può essere usata per
  le directory.} per cancellare i file e la funzione \func{rmdir} per
cancellare le directory; si tenga presente che per alcune implementazioni del
protocollo NFS utilizzare questa funzione può comportare la scomparsa di file
ancora in uso.

Per cambiare nome ad un file o a una directory (che devono comunque essere
nello stesso filesystem) si usa invece la funzione \funcd{rename},\footnote{la
  funzione è definita dallo standard ANSI C, ma si applica solo per i file, lo
  standard POSIX estende la funzione anche alle directory.} il cui prototipo
è:
\begin{prototype}{stdio.h}
  {int rename(const char *oldpath, const char *newpath)} 
  
  Rinomina un file.
  
  \bodydesc{La funzione restituisce zero in caso di successo e -1 per un
    errore, nel qual caso il file non viene toccato. La variabile
    \var{errno} viene impostata secondo i seguenti codici di errore:
  \begin{errlist} 
  \item[\errcode{EISDIR}] \param{newpath} è una directory mentre
    \param{oldpath} non è una directory.
  \item[\errcode{EXDEV}] \param{oldpath} e \param{newpath} non sono sullo
    stesso filesystem.
  \item[\errcode{ENOTEMPTY}] \param{newpath} è una directory già esistente e
    non vuota.
  \item[\errcode{EBUSY}] o \param{oldpath} o \param{newpath} sono in uso da
    parte di qualche processo (come directory di lavoro o come radice) o del
    sistema (come \itindex{mount~point} \textit{mount point}).
  \item[\errcode{EINVAL}] \param{newpath} contiene un prefisso di
    \param{oldpath} o più in generale si è cercato di creare una directory come
    sotto-directory di se stessa.
  \item[\errcode{ENOTDIR}] uno dei componenti dei \itindex{pathname}
    \textit{pathname} non è una directory o \param{oldpath} è una directory e
    \param{newpath} esiste e non è una directory.
  \end{errlist} 
  ed inoltre \errval{EACCES}, \errval{EPERM}, \errval{EMLINK},
  \errval{ENOENT}, \errval{ENOMEM}, \errval{EROFS}, \errval{ELOOP} e
  \errval{ENOSPC}.}
\end{prototype}

La funzione rinomina il file \param{oldpath} in \param{newpath}, eseguendo se
necessario lo spostamento di un file fra directory diverse. Eventuali altri
link diretti allo stesso file non vengono influenzati.

Il comportamento della funzione è diverso a seconda che si voglia rinominare
un file o una directory; se ci riferisce ad un file allora \param{newpath}, se
esiste, non deve essere una directory (altrimenti si ha l'errore
\errcode{EISDIR}). Nel caso \param{newpath} indichi un file esistente questo
viene cancellato e rimpiazzato (atomicamente).

Se \param{oldpath} è una directory allora \param{newpath}, se esiste, deve
essere una directory vuota, altrimenti si avranno gli errori \errcode{ENOTDIR}
(se non è una directory) o \errcode{ENOTEMPTY} (se non è vuota). Chiaramente
\param{newpath} non può contenere \param{oldpath} altrimenti si avrà un errore
\errcode{EINVAL}.

Se \param{oldpath} si riferisce ad un link simbolico questo sarà rinominato; se
\param{newpath} è un link simbolico verrà cancellato come qualunque altro
file.  Infine qualora \param{oldpath} e \param{newpath} siano due nomi dello
stesso file lo standard POSIX prevede che la funzione non dia errore, e non
faccia nulla, lasciando entrambi i nomi; Linux segue questo standard, anche
se, come fatto notare dal manuale delle \textit{glibc}, il comportamento più
ragionevole sarebbe quello di cancellare \param{oldpath}.

Il vantaggio nell'uso di questa funzione al posto della chiamata successiva di
\func{link} e \func{unlink} è che l'operazione è eseguita atomicamente, non
può esistere cioè nessun istante in cui un altro processo può trovare attivi
entrambi i nomi dello stesso file, o, in caso di sostituzione di un file
esistente, non trovare quest'ultimo prima che la sostituzione sia stata
eseguita.

In ogni caso se \param{newpath} esiste e l'operazione fallisce per un qualche
motivo (come un crash del kernel), \func{rename} garantisce di lasciare
presente un'istanza di \param{newpath}. Tuttavia nella sovrascrittura potrà
esistere una finestra in cui sia \param{oldpath} che \param{newpath} fanno
riferimento allo stesso file.


\subsection{I link simbolici}
\label{sec:file_symlink}

Come abbiamo visto in sez.~\ref{sec:file_link} la funzione \func{link} crea
riferimenti agli \itindex{inode} \textit{inode}, pertanto può funzionare
soltanto per file che risiedono sullo stesso filesystem e solo per un
filesystem di tipo Unix.  Inoltre abbiamo visto che in Linux non è consentito
eseguire un link diretto ad una directory.

Per ovviare a queste limitazioni i sistemi Unix supportano un'altra forma di
link (i cosiddetti \textit{soft link} o \textit{symbolic link}), che sono,
come avviene in altri sistemi operativi, dei file speciali che contengono
semplicemente il riferimento ad un altro file (o directory). In questo modo è
possibile effettuare link anche attraverso filesystem diversi, a file posti in
filesystem che non supportano i link diretti, a delle directory, ed anche a
file che non esistono ancora.

Il sistema funziona in quanto i link simbolici sono riconosciuti come tali dal
kernel\footnote{è uno dei diversi tipi di file visti in
  tab.~\ref{tab:file_file_types}, contrassegnato come tale
  nell'\textit{inode}, e riconoscibile dal valore del campo \var{st\_mode}
  della struttura \struct{stat} (vedi sez.~\ref{sec:file_stat}).}  per cui
alcune funzioni di libreria (come \func{open} o \func{stat}) quando ricevono
come argomento un link simbolico vengono automaticamente applicate al file da
esso specificato.  La funzione che permette di creare un nuovo link simbolico
è \funcd{symlink}, ed il suo prototipo è:
\begin{prototype}{unistd.h}
  {int symlink(const char *oldpath, const char *newpath)} 
  Crea un nuovo link simbolico di nome \param{newpath} il cui contenuto è
  \param{oldpath}.
  
  \bodydesc{La funzione restituisce zero in caso di successo e -1 per un
    errore, nel qual caso la variabile \var{errno} assumerà i valori:
  \begin{errlist}
  \item[\errcode{EPERM}] il filesystem che contiene \param{newpath} non
    supporta i link simbolici.
  \item[\errcode{ENOENT}] una componente di \param{newpath} non esiste o
    \param{oldpath} è una stringa vuota.
  \item[\errcode{EEXIST}] esiste già un file \param{newpath}.
  \item[\errcode{EROFS}] \param{newpath} è su un filesystem montato in sola
    lettura.
  \end{errlist}
  ed inoltre \errval{EFAULT}, \errval{EACCES}, \errval{ENAMETOOLONG},
  \errval{ENOTDIR}, \errval{ENOMEM}, \errval{ELOOP}, \errval{ENOSPC} e
  \errval{EIO}.}
\end{prototype}

Si tenga presente che la funzione non effettua nessun controllo sull'esistenza
di un file di nome \param{oldpath}, ma si limita ad inserire quella stringa
nel link simbolico. Pertanto un link simbolico può anche riferirsi ad un file
che non esiste: in questo caso si ha quello che viene chiamato un
\textit{dangling link}, letteralmente un \textsl{link ciondolante}.

Come accennato i link simbolici sono risolti automaticamente dal kernel
all'invocazione delle varie system call; in tab.~\ref{tab:file_symb_effect} si
è riportato un elenco dei comportamenti delle varie funzioni di libreria che
operano sui file nei confronti della risoluzione dei link simbolici,
specificando quali seguono il link simbolico e quali invece possono operare
direttamente sul suo contenuto.
\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 link simbolici da parte di alcune funzioni.}
  \label{tab:file_symb_effect}
\end{table}

\footnotetext{a partire dalla serie 2.0, e contrariamente a quanto indicato
  dallo standard POSIX, si veda quanto detto in sez.~\ref{sec:file_link}.}

Si noti che non si è specificato il comportamento delle funzioni che operano
con i file descriptor, in quanto la risoluzione del link simbolico viene in
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 link simbolici, occorrono funzioni apposite per accedere
alle informazioni del link invece che a quelle del file a cui esso fa
riferimento. Quando si vuole leggere il contenuto di un link simbolico si usa
la funzione \funcd{readlink}, il cui prototipo è:
\begin{prototype}{unistd.h}
{int readlink(const char *path, char *buff, size\_t size)} 
  Legge il contenuto del link simbolico indicato da \param{path} nel buffer
  \param{buff} di dimensione \param{size}.
  
  \bodydesc{La funzione restituisce il numero di caratteri letti dentro
    \param{buff} o -1 per un errore, nel qual caso la variabile
    \var{errno} assumerà i valori:
  \begin{errlist}
  \item[\errcode{EINVAL}] \param{path} non è un link simbolico o \param{size}
    non è positiva.
  \end{errlist}
  ed inoltre \errval{ENOTDIR}, \errval{ENAMETOOLONG}, \errval{ENOENT},
  \errval{EACCES}, \errval{ELOOP}, \errval{EIO}, \errval{EFAULT} e
  \errval{ENOMEM}.}
\end{prototype}

La funzione apre il link simbolico, ne legge il contenuto, lo scrive nel
buffer, e lo richiude. Si tenga presente che la funzione non termina la
stringa con un carattere nullo e la tronca alla dimensione specificata da
\param{size} per evitare di sovrascrivere oltre le dimensioni del buffer.

\begin{figure}[htb]
  \centering
  \includegraphics[width=8.5cm]{img/link_loop}
  \caption{Esempio di loop nel filesystem creato con un link simbolico.}
  \label{fig:file_link_loop}
\end{figure}

Un caso comune che si può avere con i link simbolici è la creazione dei
cosiddetti \textit{loop}. La situazione è illustrata in
fig.~\ref{fig:file_link_loop}, che riporta la struttura della directory
\file{/boot}. Come si vede si è creato al suo interno un link simbolico che
punta di nuovo a \file{/boot}.\footnote{il loop mostrato in
  fig.~\ref{fig:file_link_loop} è un usato per poter permettere a \cmd{grub}
  (un bootloader in grado di leggere direttamente da vari filesystem il file
  da lanciare come sistema operativo) di vedere i file contenuti nella
  directory \file{/boot} con lo stesso \textit{pathname} con cui verrebbero
  visti dal sistema operativo, anche se essi si trovano, come accade spesso,
  su una partizione separata (che \cmd{grub}, all'avvio, vede come radice).}

Questo può causare problemi per tutti quei programmi che effettuano la
scansione di una directory senza tener conto dei link simbolici, ad esempio se
lanciassimo un comando del tipo \code{grep -r linux *}, il loop nella
directory porterebbe il comando ad esaminare \file{/boot}, \file{/boot/boot},
\file{/boot/boot/boot} e così via.

Per questo motivo il kernel e le librerie prevedono che nella risoluzione di
un \itindex{pathname} \textit{pathname} possano essere seguiti un numero
limitato di link 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}.

Un punto da tenere sempre presente è che, come abbiamo accennato, un link
simbolico può fare riferimento anche ad un file che non esiste; ad esempio
possiamo creare un file temporaneo nella nostra directory con un link del
tipo:
\begin{verbatim}
$ ln -s /tmp/tmp_file temporaneo
\end{verbatim}%$
anche se \file{/tmp/tmp\_file} non esiste. Questo può generare confusione, in
quanto aprendo in scrittura \file{temporaneo} verrà creato
\file{/tmp/tmp\_file} e scritto; ma accedendo in sola lettura a
\file{temporaneo}, ad esempio con \cmd{cat}, otterremmo:
\begin{verbatim}
$ cat temporaneo
cat: temporaneo: No such file or directory
\end{verbatim}%$
con un errore che può sembrare sbagliato, dato che un'ispezione con \cmd{ls}
ci mostrerebbe invece l'esistenza di \file{temporaneo}.


\subsection{La creazione e la cancellazione delle directory} 
\label{sec:file_dir_creat_rem}

Benché in sostanza le directory non siano altro che dei file contenenti
elenchi di nomi ed \itindex{inode} \textit{inode}, non è possibile trattarle
come file ordinari e devono essere create direttamente dal kernel attraverso
una opportuna system call.\footnote{questo è quello che permette anche,
  attraverso l'uso del VFS, l'utilizzo di diversi formati per la gestione dei
  suddetti elenchi, dalle semplici liste a strutture complesse come alberi
  binari, hash, ecc. che consentono una ricerca veloce quando il numero di
  file è molto grande.}  La funzione usata per creare una directory è
\funcd{mkdir}, ed il suo prototipo è:
\begin{functions}
  \headdecl{sys/stat.h}
  \headdecl{sys/types.h}
  \funcdecl{int mkdir(const char *dirname, mode\_t mode)} 

  Crea una nuova directory.
  
  \bodydesc{La funzione restituisce zero in caso di successo e -1 per un
    errore, nel qual caso \var{errno} assumerà i valori:
  \begin{errlist}
  \item[\errcode{EEXIST}] un file (o una directory) con quel nome esiste di
    già.
  \item[\errcode{EACCES}] non c'è il permesso di scrittura per la directory in
    cui si vuole inserire la nuova directory.
  \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 anche \errval{EPERM}, \errval{EFAULT}, \errval{ENAMETOOLONG},
  \errval{ENOENT}, \errval{ENOTDIR}, \errval{ENOMEM}, \errval{ELOOP},
  \errval{EROFS}.}
\end{functions}

La funzione crea una nuova directory vuota, che contiene cioè solo le due voci
standard presenti in ogni directory (cioè ``\file{.}'' e ``\file{..}''), con
il nome indicato dall'argomento \param{dirname}. Il nome può essere indicato
sia come \itindex{pathname} \textit{pathname} assoluto che come
\itindex{pathname} \textit{pathname} relativo.

I permessi di accesso (vedi sez.~\ref{sec:file_access_control}) con cui la
directory viene creata sono specificati dall'argomento \param{mode}, i cui
possibili valori sono riportati in tab.~\ref{tab:file_permission_const}; si
tenga presente che questi sono modificati dalla maschera di creazione dei file
(si veda sez.~\ref{sec:file_perm_management}).  La titolarità della nuova
directory è impostata secondo quanto riportato in
sez.~\ref{sec:file_ownership_management}.

La funzione che permette la cancellazione di una directory è invece
\funcd{rmdir}, ed il suo prototipo è:
\begin{prototype}{sys/stat.h}{int rmdir(const char *dirname)} 
  Cancella una directory.

  \bodydesc{La funzione restituisce zero in caso di successo e -1 per un
    errore, nel qual caso \var{errno} assumerà i valori:
  \begin{errlist}
  \item[\errcode{EPERM}] il filesystem non supporta la cancellazione di
    directory, oppure la directory che contiene \param{dirname} ha lo
    \itindex{sticky~bit} \textit{sticky bit} impostato e l'\acr{uid} effettivo
    del processo non corrisponde al proprietario della directory.
  \item[\errcode{EACCES}] non c'è il permesso di scrittura per la directory
    che contiene la directory che si vuole cancellare, o non c'è il permesso
    di attraversare (esecuzione) una delle directory specificate in
    \param{dirname}.
  \item[\errcode{EBUSY}] la directory specificata è la directory di lavoro o la
    radice di qualche processo.
  \item[\errcode{ENOTEMPTY}] la directory non è vuota.
  \end{errlist}
  ed inoltre anche \errval{EFAULT}, \errval{ENAMETOOLONG}, \errval{ENOENT},
  \errval{ENOTDIR}, \errval{ENOMEM}, \errval{ELOOP}, \errval{EROFS}.}
\end{prototype}

La funzione cancella la directory \param{dirname}, che deve essere vuota (la
directory deve cioè contenere soltanto le due voci standard ``\file{.}'' e
``\file{..}'').  Il nome può essere indicato con il \itindex{pathname}
\textit{pathname} assoluto o relativo.

La modalità con cui avviene la cancellazione è analoga a quella di
\func{unlink}: fintanto che il numero di link \itindex{inode}
all'\textit{inode} della directory non diventa nullo e nessun processo ha la
directory aperta lo spazio occupato su disco non viene rilasciato. Se un
processo ha la directory aperta la funzione rimuove il link \itindex{inode}
all'\textit{inode} e nel caso sia l'ultimo, pure le voci standard ``\file{.}''
e ``\file{..}'', a questo punto il kernel non consentirà di creare più nuovi
file nella directory.


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

\index{file!di~dispositivo|(} 

Finora abbiamo parlato esclusivamente di file, directory e link simbolici; in
sez.~\ref{sec:file_file_types} abbiamo visto però che il sistema prevede pure
degli altri tipi di file speciali, come i file di dispositivo, le fifo ed i
socket (questi ultimi sono un caso a parte, essendo associati anche alla
comunicazione via rete, per cui ci saranno trattati in dettaglio a partire da
cap.~\ref{cha:socket_intro}).

La manipolazione delle caratteristiche di questi diversi tipi di file e la
loro cancellazione può essere effettuata con le stesse funzioni che operano
sui file regolari; ma quando li si devono creare sono necessarie delle
funzioni apposite. La prima di queste funzioni è \funcd{mknod}, il cui
prototipo è:
\begin{functions}
  \headdecl{sys/types.h}
  \headdecl{sys/stat.h}
  \headdecl{fcntl.h}
  \headdecl{unistd.h}
  \funcdecl{int mknod(const char *pathname, mode\_t mode, dev\_t dev)} 
  
  Crea un \textit{inode} del tipo specificato sul filesystem.
  
  \bodydesc{La funzione restituisce zero in caso di successo e -1 per un
    errore, nel qual caso \var{errno} assumerà i valori:
  \begin{errlist}
  \item[\errcode{EPERM}] non si hanno privilegi sufficienti a creare
    l'\texttt{inode}, o il filesystem su cui si è cercato di
    creare \param{pathname} non supporta l'operazione.
  \item[\errcode{EINVAL}] il valore di \param{mode} non indica un file, una
    fifo, un socket o un dispositivo.
  \item[\errcode{EEXIST}] \param{pathname} esiste già o è un link simbolico.
  \end{errlist}
  ed inoltre anche \errval{EFAULT}, \errval{EACCES}, \errval{ENAMETOOLONG},
  \errval{ENOENT}, \errval{ENOTDIR}, \errval{ENOMEM}, \errval{ELOOP},
  \errval{ENOSPC}, \errval{EROFS}.}
\end{functions}

La funzione, come suggerisce il nome, permette di creare un ``\textsl{nodo}''
sul filesystem, e viene in genere utilizzata per creare i file di dispositivo,
ma si può usare anche per creare file regolari. L'argomento
\param{mode} specifica sia il tipo di file che si vuole creare che i relativi
permessi, secondo i valori riportati in tab.~\ref{tab:file_mode_flags}, che
vanno combinati con un OR binario. I permessi sono comunque modificati nella
maniera usuale dal valore di \itindex{umask} \textit{umask} (si veda
sez.~\ref{sec:file_perm_management}).

Per il tipo di file può essere specificato solo uno fra i seguenti valori:
\const{S\_IFREG} per un file regolare (che sarà creato vuoto),
\const{S\_IFBLK} per un dispositivo a blocchi, \const{S\_IFCHR} per un
dispositivo a caratteri, \const{S\_IFSOCK} per un socket e \const{S\_IFIFO}
per una fifo;\footnote{con Linux la funzione non può essere usata per creare
  directory o link simbolici, si dovranno usare le funzioni \func{mkdir} e
  \func{symlink} a questo dedicate.} un valore diverso comporterà l'errore
\errcode{EINVAL}.  

Qualora si sia specificato in \param{mode} un file di dispositivo (vale a dire
o \const{S\_IFBLK} o \const{S\_IFCHR}), il valore di \param{dev} dovrà essere
usato per indicare a quale dispositivo si fa riferimento, altrimenti il suo
valore verrà ignorato.  Solo l'amministratore può creare un file di
dispositivo usando questa funzione (il processo deve avere la
\itindex{capabilities} \textit{capability} \const{CAP\_MKNOD}), ma in
Linux\footnote{questo è un comportamento specifico di Linux, la funzione non è
  prevista dallo standard POSIX.1 originale, mentre è presente in SVr4 e
  4.4BSD, ma esistono differenze nei comportamenti e nei codici di errore,
  tanto che questa è stata introdotta in POSIX.1-2001 con una nota che la
  definisce portabile solo quando viene usata per creare delle fifo, ma
  comunque deprecata essendo utilizzabile a tale scopo la specifica
  \func{mkfifo}.} l'uso per la creazione di un file ordinario, di una fifo o
di un socket è consentito anche agli utenti normali.

I nuovi \itindex{inode} \textit{inode} creati con \func{mknod} apparterranno
al proprietario e al gruppo del processo che li ha creati, a meno che non si
sia attivato il bit \acr{sgid} per la directory o sia stata attivata la
semantica BSD per il filesystem (si veda
sez.~\ref{sec:file_ownership_management}) in cui si va a creare
\itindex{inode} l'\textit{inode}.

Nella creazione di un file di dispositivo occorre poi specificare
correttamente il valore di \param{dev}; questo infatti è di tipo
\type{dev\_t}, che è un tipo primitivo (vedi
tab.~\ref{tab:intro_primitive_types}) riservato per indicare un
\textsl{numero} di dispositivo; il kernel infatti identifica ciascun
dispositivo con un valore numerico. Originariamente questo era un intero a 16
bit diviso in due parti di 8 bit chiamate rispettivamente
\itindex{major~number} \textit{major number} e \itindex{minor~number}
\textit{minor number}, che sono poi i due numeri mostrati dal comando
\texttt{ls -l} al posto della dimensione quando lo si esegue su un file di
dispositivo.

Il \itindex{major~number} \textit{major number} identifica una classe di
dispositivi (ad esempio la seriale, o i dischi IDE) e serve in sostanza per
indicare al kernel quale è il modulo che gestisce quella classe di
dispositivi; per identificare uno specifico dispositivo di quella classe (ad
esempio una singola porta seriale, o una partizione di un disco) si usa invece
il \itindex{minor~number} \textit{minor number}. L'elenco aggiornato di questi
numeri con le relative corrispondenze ai vari dispositivi può essere trovato
nel file \texttt{Documentation/devices.txt} allegato alla documentazione dei
sorgenti del kernel.

Data la crescita nel numero di dispositivi supportati, ben presto il limite
massimo di 256 si è rivelato troppo basso, e nel passaggio dai kernel della
serie 2.4 alla serie 2.6 è stata aumentata a 32 bit la dimensione del tipo
\type{dev\_t}, con delle dimensioni passate a 12 bit per il
\itindex{major~number} \textit{major number} e 20 bit per il
\itindex{minor~number} \textit{minor number}. La transizione però ha anche
comportato il passaggio di \type{dev\_t} a \index{tipo!opaco} tipo opaco, e la
necessità di specificare il numero tramite delle opportune macro, così da non
avere problemi di compatibilità con eventuali ulteriori estensioni.

Le macro sono definite nel file \file{sys/sysmacros.h}, che viene
automaticamente incluso quando si include \file{sys/types.h}; si possono
pertanto ottenere i valori del \itindex{major~number} \textit{major number} e
\itindex{minor~number} \textit{minor number} di un dispositivo rispettivamente
con le macro \macro{major} e \macro{minor}:
\begin{functions}
  \headdecl{sys/types.h}
  \funcdecl{int \macro{major}(dev\_t dev)}
  Restituisce il \itindex{major~number} \textit{major number} del dispositivo
  \param{dev}.
  
  \funcdecl{int \macro{minor}(dev\_t dev)}
  Restituisce il \itindex{minor~number} \textit{minor number} del dispositivo
  \param{dev}.
\end{functions}
\noindent mentre una volta che siano noti \itindex{major~number} \textit{major
  number} e \itindex{minor~number} \textit{minor number} si potrà costruire il
relativo identificativo con la macro \macro{makedev}:
\begin{functions}
  \headdecl{sys/types.h}
  \funcdecl{dev\_t \macro{minor}(int major, int minor)}

  Restituisce l'identificativo di un dispositivo dati \itindex{major~number}
  \textit{major number} e \itindex{minor~number} \textit{minor number}.
\end{functions}

\index{file!di~dispositivo|)}

Infine con lo standard POSIX.1-2001 è stata introdotta una funzione specifica
per creare una fifo (tratteremo le fifo in in sez.~\ref{sec:ipc_named_pipe});
la funzione è \funcd{mkfifo} ed il suo prototipo è:
\begin{functions}
  \headdecl{sys/types.h} \headdecl{sys/stat.h} 
  
  \funcdecl{int mkfifo(const char *pathname, mode\_t mode)} 
  
  Crea una fifo.
  
  \bodydesc{La funzione restituisce zero in caso di successo e -1 per un
    errore, nel qual caso \var{errno} assumerà i valori \errval{EACCES},
    \errval{EEXIST}, \errval{ENAMETOOLONG}, \errval{ENOENT}, \errval{ENOSPC},
    \errval{ENOTDIR} e \errval{EROFS}.}
\end{functions}

La funzione crea la fifo \param{pathname} con i permessi \param{mode}. Come
per \func{mknod} il file \param{pathname} non deve esistere (neanche come link
simbolico); al solito i permessi specificati da \param{mode} vengono
modificati dal valore di \itindex{umask} \textit{umask}.



\subsection{Accesso alle directory}
\label{sec:file_dir_read}

Benché le directory alla fine non siano altro che dei file che contengono
delle liste di nomi ed \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 VFS del kernel prevede una apposita
funzione per la lettura delle directory.

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 file stream dell'interfaccia standard ANSI C di
cap.~\ref{cha:files_std_interface}). La prima funzione di questa interfaccia è
\funcd{opendir}, il cui prototipo è:
\begin{functions}
  \headdecl{sys/types.h} \headdecl{dirent.h} 
  
  \funcdecl{DIR * opendir(const char *dirname)} 
  
  Apre un \textit{directory stream}.
  
  \bodydesc{La funzione restituisce un puntatore al \textit{directory stream}
    in caso di successo e \val{NULL} per un errore, nel qual caso \var{errno}
    assumerà i valori \errval{EACCES}, \errval{EMFILE}, \errval{ENFILE},
    \errval{ENOENT}, \errval{ENOMEM} e \errval{ENOTDIR}.}
\end{functions}

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 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}, 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 le \acr{glibc} ma non presente in POSIX fino alla revisione
  POSIX.1-2008, per questo per poterla utilizzare fino alla versione 2.10
  delle \acr{glibc} era necessario definire le macro \macro{\_BSD\_SOURCE} o
  \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{functions}
  \headdecl{sys/types.h} \headdecl{dirent.h} 
  
  \funcdecl{int dirfd(DIR * dir)} 
  
  Restituisce il file descriptor associato ad un \textit{directory stream}.
  
  \bodydesc{La funzione restituisce il file descriptor (un valore positivo) in
    caso di successo e -1 in caso di errore.}
\end{functions}

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 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 delle \acr{glibc}, ed è stata introdotta nello standard
  POSIX solo a partire dalla revisione POSIX.1-2008, prima della versione 2.10
  delle \acr{glibc} per poterla utilizzare era necessario definire la macro
  \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{functions}
  \headdecl{sys/types.h} \headdecl{dirent.h}
  
  \funcdecl{DIR * fdopendir(int fd)} 
  
  Associa un \textit{directory stream} al file descriptor \param{fd}.
  
  \bodydesc{La funzione restituisce un puntatore al \textit{directory stream}
    in caso di successo e \val{NULL} per un errore, nel qual caso \var{errno}
    assumerà il valore \errval{EBADF}.}
\end{functions}

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 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 suo prototipo è:
\begin{functions}
  \headdecl{sys/types.h} \headdecl{dirent.h} 
  
  \funcdecl{struct dirent *readdir(DIR *dir)}
  
  Legge una voce dal \textit{directory stream}.
  
  \bodydesc{La funzione restituisce il puntatore alla struttura contenente i
    dati in caso di successo e \val{NULL} altrimenti, in caso di
    \textit{directory stream} non valido \var{errno} assumerà il valore
    \errval{EBADF}, il valore \val{NULL} viene restituito anche quando si
    raggiunge la fine dello stream.}
\end{functions}

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.

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

I dati 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
restituisce il puntatore alla struttura; si tenga presente però che
quest'ultima è allocata staticamente, per cui 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, \func{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{functions}
  \headdecl{sys/types.h} \headdecl{dirent.h} 
  
  \funcdecl{int readdir\_r(DIR *dir, struct dirent *entry,
          struct dirent **result)}
  
  Legge una voce dal \textit{directory stream}.
  
  \bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di
    errore, gli errori sono gli stessi di \func{readdir}.}
\end{functions}

La funzione restituisce in \param{result} (come
\itindex{value~result~argument} \textit{value result argument}) l'indirizzo
dove sono stati salvati i dati, che di norma corrisponde a quello della
struttura precedentemente allocata e specificata dall'argomento \param{entry},
anche se non è assicurato che la funzione usi lo spazio fornito dall'utente.

I vari campi di \struct{dirent} contengono le informazioni relative alle voci
presenti nella directory; sia BSD che SVr4 prevedono che siano sempre presenti
il campo \var{d\_name},\footnote{lo standard POSIX prevede invece solo la
  presenza del campo \var{d\_fileno}, identico \var{d\_ino}, che in Linux è
  definito come alias di quest'ultimo; il campo \var{d\_name} è considerato
  dipendente dall'implementazione.} che contiene il nome del file nella forma
di una stringa terminata da uno zero,\footnote{lo standard POSIX non specifica
  una lunghezza, ma solo un limite \const{NAME\_MAX}; in SVr4 la lunghezza del
  campo è definita come \code{NAME\_MAX+1} che di norma porta al valore di 256
  byte usato anche in Linux.} ed il campo \var{d\_ino}, che contiene il numero
di \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; 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}.

\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}     & Link 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 quanto riguarda il significato dei campi opzionali, il campo \var{d\_type}
indica il tipo di file (se fifo, directory, link simbolico, ecc.), e consente
di evitare una successiva chiamata a \func{lstat} per determinarlo. I suoi
possibili valori sono riportati in tab.~\ref{tab:file_dtype_macro}. Si tenga
presente che questo valore è disponibile solo per i filesystem che ne
supportano la restituzione (fra questi i più noti sono \textsl{btrfs},
\textsl{ext2}, \textsl{ext3}, e \textsl{ext4}), per gli altri si otterrà
sempre il valore \const{DT\_UNKNOWN}.\footnote{inoltre fino alla versione 2.1
  delle \acr{glibc}, pur essendo il campo \var{d\_type} presente, il suo uso
  non era implementato, e veniva restituito comunque il valore
  \const{DT\_UNKNOWN}.}

Per la conversione da e verso l'analogo valore mantenuto dentro il campo
\var{st\_mode} di \struct{stat} sono definite anche due macro di conversione,
\macro{IFTODT} e \macro{DTTOIF}:
\begin{functions}
  \funcdecl{int IFTODT(mode\_t MODE)} Converte il tipo di file dal formato di
  \var{st\_mode} a quello di \var{d\_type}.
  
  \funcdecl{mode\_t DTTOIF(int DTYPE)} Converte il tipo di file dal formato di
  \var{d\_type} a quello di \var{st\_mode}.
\end{functions}

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 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{prototype}{dirent.h}{void seekdir(DIR *dir, off\_t offset)}
  Cambia la posizione all'interno di un \textit{directory stream}.
\end{prototype}

La funzione non ritorna nulla e non segnala errori, è però necessario che il
valore dell'argomento \param{offset} sia valido per lo stream \param{dir};
esso pertanto deve essere stato ottenuto o dal valore di \var{d\_off} di
\struct{dirent} o dal valore restituito dalla funzione \funcd{telldir}, che
legge la posizione corrente; il prototipo di quest'ultima è:\footnote{prima
  delle \acr{glibc} 2.1.1 la funzione restituiva un valore di tipo
  \type{off\_t}, sostituito a partire dalla versione 2.1.2 da \ctyp{long} per
  conformità a POSIX.1-2001.}
\begin{prototype}{dirent.h}{long telldir(DIR *dir)}
  Ritorna la posizione corrente in un \textit{directory stream}.
  
  \bodydesc{La funzione restituisce la posizione corrente nello stream (un
    numero positivo) in caso di successo, e -1 altrimenti, nel qual caso
    \var{errno} assume solo il valore di \errval{EBADF}, corrispondente ad un
    valore errato per \param{dir}.}
\end{prototype}

La sola funzione di posizionamento nello stream prevista originariamente dallo
standard POSIX è \funcd{rewinddir}, che riporta la posizione a quella
iniziale; il suo prototipo è:
\begin{functions}
  \headdecl{sys/types.h} \headdecl{dirent.h} 
  
  \funcdecl{void rewinddir(DIR *dir)}
  
  Si posiziona all'inizio di un \textit{directory stream}.
\end{functions}

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{functions}
  \headdecl{sys/types.h} \headdecl{dirent.h} 
  
  \funcdecl{int closedir(DIR * dir)} 
  
  Chiude un \textit{directory stream}.
  
  \bodydesc{La funzione restituisce 0 in caso di successo e -1 altrimenti, nel
    qual caso \var{errno} assume il valore \errval{EBADF}.}
\end{functions}

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{prototype}{dirent.h}{int scandir(const char *dir, 
    struct dirent ***namelist, int(*filter)(const struct dirent *),
    int(*compar)(const struct dirent **, const struct dirent **))} 
  
  Esegue una scansione di un \textit{directory stream}.
  
  \bodydesc{La funzione restituisce in caso di successo il numero di voci
    trovate, e -1 altrimenti.}
\end{prototype}

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 (quella passata con
l'argomento \param{filter}) e l'ordinamento di tutte le voci selezionate
(quella 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 \func{filter} non
viene fatta nessuna selezione e si ottengono tutte le voci presenti.

Le voci selezionate possono essere riordinate tramite \func{qsort}, le modalità
del riordinamento possono essere personalizzate usando la funzione
\param{compar} come criterio di ordinamento di \func{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.}

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{functions}
  \headdecl{dirent.h} 
  
  \funcdecl{int alphasort(const void *a, const void *b)} 

  \funcdecl{int versionsort(const void *a, const void *b)} 
  
  Funzioni per l'ordinamento delle voci di \textit{directory stream}.
  
  \bodydesc{Le funzioni restituiscono un valore minore, uguale o maggiore di
    zero qualora il primo argomento sia rispettivamente minore, uguale o
    maggiore del secondo.}
\end{functions}

La funzione \func{alphasort} deriva da BSD ed è presente in Linux fin dalle
\acr{libc4}\footnote{la versione delle \acr{libc4} e \acr{libc5} usa però come
  argomenti dei puntatori a delle strutture \struct{dirent}; le glibc usano il
  prototipo originario di BSD, mostrato anche nella definizione, che prevede
  puntatori a \ctyp{void}.} e deve essere specificata come argomento
\param{compar} per ottenere un ordinamento alfabetico (secondo il valore del
campo \var{d\_name} delle varie voci). Le \acr{glibc} prevedono come
estensione\footnote{le glibc, a partire dalla versione 2.1, effettuano anche
  l'ordinamento alfabetico tenendo conto delle varie localizzazioni, usando
  \func{strcoll} al posto di \func{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 potrà essere
trovato coi sorgenti allegati 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
\func{DirScan} 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 \func{DirScan} 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/DirScan.c}
  \end{minipage}
  \caption{Codice della funzione di scansione di una directory contenuta nel
    file \file{DirScan.c}.} 
  \label{fig:file_dirscan}
\end{figure}

Tutto il grosso del lavoro è svolto dalla funzione \func{DirScan}, 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
stream sulla directory passata come primo argomento, stampando un messaggio in
caso di errore.

Il passo successivo (\texttt{\small 23--24}) è cambiare 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 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 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}

\itindbeg{pathname}

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 \struct{task\_struct} (vedi fig.~\ref{fig:proc_task_struct}), più
  precisamente nel campo \texttt{pwd} della sotto-struttura
  \struct{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 corrente
resta la stessa quando viene creato un processo figlio (vedi
sez.~\ref{sec:proc_fork}), la directory corrente della shell diventa anche la
directory corrente 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 di libreria,
\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{prototype}{unistd.h}{char *getcwd(char *buffer, size\_t size)}
  Legge il \textit{pathname} della directory di lavoro corrente.
  
  \bodydesc{La funzione restituisce il puntatore \param{buffer} se riesce,
    \val{NULL} se fallisce, in quest'ultimo caso la variabile
    \var{errno} è impostata con i seguenti codici di errore:
  \begin{errlist}
  \item[\errcode{EINVAL}] l'argomento \param{size} è zero e \param{buffer} non
    è nullo.
  \item[\errcode{ERANGE}] l'argomento \param{size} è più piccolo della
    lunghezza del \textit{pathname}. 
  \item[\errcode{EACCES}] manca il permesso di lettura o di ricerca su uno dei
    componenti del \textit{pathname} (cioè su una delle directory superiori
    alla corrente).
  \item[\errcode{ENOENT}] la directory di lavoro è stata eliminata.
  \end{errlist}}
\end{prototype}

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 una
volta cessato il suo utilizzo.

Di questa funzione esiste una versione \code{char *getwd(char *buffer)} fatta
per compatibilità all'indietro con BSD, che non consente di specificare la
dimensione del buffer; esso deve essere allocato in precedenza ed avere una
dimensione superiore a \const{PATH\_MAX} (di solito 256 byte, vedi
sez.~\ref{sec:sys_limits}); il problema è che in Linux non esiste una
dimensione superiore per 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.

Un uso comune di \func{getcwd} è quello di salvare la directory di lavoro
iniziale 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
la directory corrente (vale a dire ``\texttt{.}'') e tornarvi in seguito con
\func{fchdir}. 

Una seconda usata per ottenere la directory di lavoro è \code{char
  *get\_current\_dir\_name(void)} che è sostanzialmente equivalente ad una
\code{getcwd(NULL, 0)}, con la sola differenza che essa ritorna il valore
della variabile di ambiente \val{PWD}, che essendo costruita dalla shell può
contenere un \textit{pathname} comprendente anche dei link simbolici. Usando
\func{getcwd} infatti, essendo il \textit{pathname} ricavato risalendo
all'indietro l'albero della directory, si perderebbe traccia di ogni passaggio
attraverso eventuali link simbolici.

Per cambiare la directory di lavoro si può usare la funzione \funcd{chdir}
(equivalente del comando di shell \cmd{cd}) il cui nome sta appunto per
\textit{change directory}, il suo prototipo è:
\begin{prototype}{unistd.h}{int chdir(const char *pathname)} 
  Cambia la directory di lavoro in \param{pathname}.
  
  \bodydesc{La funzione restituisce 0 in caso di successo e -1 per un errore,
    nel qual caso \var{errno} assumerà i valori:
  \begin{errlist}
  \item[\errcode{ENOTDIR}] non si è specificata una directory.
  \item[\errcode{EACCES}] manca il permesso di ricerca su uno dei componenti
    di \param{path}.
  \end{errlist}
  ed inoltre \errval{EFAULT}, \errval{ENAMETOOLONG}, \errval{ENOENT},
  \errval{ENOMEM}, \errval{ELOOP} e \errval{EIO}.}
\end{prototype}
\noindent ed ovviamente \param{pathname} deve indicare una directory per la
quale si hanno i permessi di accesso.

Dato che anche le directory sono file, è possibile riferirsi ad esse anche
tramite il file descriptor, e non solo tramite il \textit{pathname}, per fare
questo si usa \funcd{fchdir}, il cui prototipo è:
\begin{prototype}{unistd.h}{int fchdir(int fd)} 
  Identica a \func{chdir}, ma usa il file descriptor \param{fd} invece del
  \textit{pathname}.
  
  \bodydesc{La funzione restituisce zero in caso di successo e -1 per un
    errore, in caso di errore \var{errno} assumerà i valori \errval{EBADF} o
    \errval{EACCES}.}
\end{prototype}
\noindent 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 accesso alla directory
specificata da \param{fd}.

\itindend{pathname}



\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}).

Le \acr{glibc} provvedono 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{prototype}{stdio.h}{char *tmpnam(char *string)}
  Genera un nome univoco per un file temporaneo.
 
  \bodydesc{La funzione ritorna il puntatore alla stringa con il nome o
  \val{NULL} in caso di fallimento. Non sono definiti errori.}
\end{prototype}

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
  \file{stdio.h}.}

Di questa funzione esiste una versione \index{funzioni!rientranti} rientrante,
\func{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{prototype}{stdio.h}{char *tempnam(const char *dir, const char *pfx)}
  Genera un nome univoco per un file temporaneo.

  \bodydesc{La funzione ritorna il puntatore alla stringa con il nome o
  \val{NULL} in caso di fallimento, \var{errno} viene impostata a
  \errval{ENOMEM} qualora fallisca l'allocazione della stringa.}
\end{prototype}

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 \const{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 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
con lo stesso nome; per questo motivo quando si usa il nome ottenuto da una di
queste funzioni occorre sempre 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 stream) che fa fallire l'apertura in caso il file sia già
esistente.

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{prototype}{stdio.h}{FILE *tmpfile(void)}
  Restituisce un file temporaneo aperto in lettura/scrittura.
  
  \bodydesc{La funzione ritorna il puntatore allo stream associato al file
    temporaneo in caso di successo e \val{NULL} in caso di errore, nel qual
    caso \var{errno} assumerà i valori:
    \begin{errlist}
    \item[\errcode{EINTR}] la funzione è stata interrotta da un segnale.
    \item[\errcode{EEXIST}] non è stato possibile generare un nome univoco.
    \end{errlist}
    ed inoltre \errval{EFAULT}, \errval{EMFILE}, \errval{ENFILE},
    \errval{ENOSPC}, \errval{EROFS} e \errval{EACCES}.}
\end{prototype}

La funzione restituisce direttamente uno stream già aperto (in modalità
\code{r+b}, si veda sez.~\ref{sec:file_fopen}) e pronto per l'uso, che viene
automaticamente cancellato alla sua chiusura o all'uscita dal programma. Lo
standard non specifica in quale directory verrà aperto il file, ma le
\acr{glibc} prima tentano con \const{P\_tmpdir} e poi con \file{/tmp}. Questa
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 \code{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{prototype}{stlib.h}{char *mktemp(char *template)}
  Genera un nome univoco per un file temporaneo.
  
  \bodydesc{La funzione ritorna il puntatore \param{template} in caso di
    successo e \val{NULL} in caso di errore, nel qual caso \var{errno}
    assumerà i valori:
    \begin{errlist}
    \item[\errcode{EINVAL}] \param{template} non termina con \code{XXXXXX}.
    \end{errlist}}
\end{prototype}

La funzionane 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 \acr{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{prototype}{stlib.h}{int mkstemp(char *template)}
  Genera un file temporaneo.
  
  \bodydesc{La funzione ritorna il file descriptor in caso di successo e
    -1 in caso di errore, nel qual caso \var{errno} assumerà i 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{prototype}

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 dalle \acr{glibc} 2.0.7, le versioni precedenti delle \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
  \const{\_GNU\_SOURCE}.} il cui prototipo è:
\begin{prototype}{stlib.h}{int mkostemp(char *template, int flags)}
  Genera un file temporaneo.
  
  \bodydesc{La funzione ritorna il file descriptor in caso di successo e
    -1 in caso di errore, con gli stessi errori di \func{mkstemp}.}
\end{prototype}
\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 nelle \acr{glibc} a partire dalla versione
  2.1.91 ed inserita nello standard POSIX.1-2008.}  il suo prototipo è:
\begin{prototype}{stlib.h}{char *mkdtemp(char *template)}
  Genera una directory temporanea.
  
  \bodydesc{La funzione ritorna il puntatore al nome della directory in caso
    successo e \val{NULL} in caso di errore, nel qual caso \var{errno}
    assumerà i 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{prototype}

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 \funcd{stat}, \funcd{fstat} e \funcd{lstat}, i cui prototipi sono:
\begin{functions}
  \headdecl{sys/types.h} 
  \headdecl{sys/stat.h} 
  \headdecl{unistd.h}

  \funcdecl{int stat(const char *file\_name, struct stat *buf)} 
  \funcdecl{int lstat(const char *file\_name, struct stat *buf)} 
  \funcdecl{int fstat(int filedes, struct stat *buf)} 
  Legge le informazioni di un file.

  \bodydesc{Le funzioni restituiscono 0 in caso di successo e -1 per un
    errore, nel qual caso \var{errno} assumerà uno dei valori: \errval{EBADF},
    \errval{ENOENT}, \errval{ENOTDIR}, \errval{ELOOP}, \errval{EFAULT},
    \errval{EACCES}, \errval{ENOMEM}, \errval{ENAMETOOLONG}.}
\end{functions}

La funzione \func{stat} legge le informazioni del file il cui pathname è
specificato dalla stringa puntata 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 link 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
\file{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}), o per il padding dei campi.

\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 \file{sys/types.h}).

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

Come riportato in tab.~\ref{tab:file_file_types} in Linux oltre ai file e alle
directory esistono altri oggetti che possono stare su un filesystem.  Il tipo
di file è ritornato dalla funzione \func{stat} come maschera binaria nel campo
\var{st\_mode} (che contiene anche le informazioni relative ai permessi) di
una struttura \struct{stat}.

Dato che il valore numerico può variare a seconda delle implementazioni, lo
standard POSIX definisce un insieme di macro per verificare il tipo di file,
queste vengono usate anche da Linux che supporta pure le estensioni allo
standard per i link simbolici e i socket definite da BSD; l'elenco completo
delle macro con cui è possibile estrarre l'informazione da \var{st\_mode} è
riportato in tab.~\ref{tab:file_type_macro}.
\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)}  & link simbolico.\\
    \macro{S\_ISSOCK}\texttt{(m)} & socket.\\
    \hline    
  \end{tabular}
  \caption{Macro per i tipi di file (definite in \texttt{sys/stat.h}).}
  \label{tab:file_type_macro}
\end{table}

Oltre alle macro di tab.~\ref{tab:file_type_macro} è 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
\file{sys/stat.h} sono definite le costanti numeriche riportate in
tab.~\ref{tab:file_mode_flags}.

Il primo valore dell'elenco di tab.~\ref{tab:file_mode_flags} è la maschera
binaria che permette di estrarre i bit nei quali viene memorizzato il tipo di
file, i valori successivi sono le costanti corrispondenti ai singoli bit, e
possono essere usati per effettuare la selezione sul tipo di file voluto, con
un'opportuna combinazione.

\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 & Link 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 & Set UID bit \itindex{suid~bit}.\\
    \const{S\_ISGID}  &  0002000 & Set GID bit \itindex{sgid~bit}.\\
    \const{S\_ISVTX}  &  0001000 & Sticky bit \itindex{sticky~bit}.\\
    \hline
%    \const{S\_IRWXU}  &  00700   & Bitmask 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   & Bitmask 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   & Bitmask 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 \file{sys/stat.h}).}
  \label{tab:file_mode_flags}
\end{table}

Ad esempio se si volesse impostare una condizione che permetta di controllare
se un file è una directory o un file ordinario si potrebbe definire la macro
di preprocessore:
\includecodesnip{listati/is_file_dir.h}
in cui prima si estraggono da \var{st\_mode} i bit relativi al tipo di file e
poi si effettua il confronto con la combinazione di tipi scelta.


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

Il campo \var{st\_size} di una struttura \struct{stat} contiene la dimensione
del file in byte, se si tratta di un file regolare. Nel caso di un link
simbolico la dimensione è quella del \itindex{pathname} \textit{pathname} che
il link stesso contiene; per le fifo questo campo è sempre nullo.

Il campo \var{st\_blocks} definisce la lunghezza del file in blocchi di 512
byte. Il campo \var{st\_blksize} infine definisce la dimensione preferita per
i trasferimenti sui file (che è la dimensione usata anche dalle librerie del C
per l'interfaccia degli stream); scrivere sul file a blocchi di dati di
dimensione inferiore sarebbe inefficiente.

Si tenga conto che la lunghezza del file riportata in \var{st\_size} non è
detto che corrisponda all'occupazione dello spazio su disco per via della
possibile esistenza dei cosiddetti \index{file!\textit{hole}} \textit{holes}
(letteralmente \textsl{buchi}) che si formano tutte le volte che si va a
scrivere su un \itindex{sparse~file} 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 le parti non scritte vengono restituiti degli zeri, si avrà lo stesso
risultato di \cmd{ls}.

Se è sempre possibile allargare un file, scrivendoci sopra od usando la
funzione \func{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 \funcd{truncate} e
\funcd{ftruncate}, i cui prototipi sono:
\begin{functions}
  \headdecl{unistd.h} 

  \funcdecl{int truncate(const char *file\_name, off\_t length)} 

  \funcdecl{int ftruncate(int fd, off\_t length))} 

  Troncano un file alla lunghezza \param{length}.

  \bodydesc{Le funzioni restituiscono zero in caso di successo e -1 per un
    errore, nel qual caso \var{errno} viene impostata opportunamente; per
    \func{ftruncate} si hanno i valori:
  \begin{errlist}
  \item[\errcode{EBADF}] \param{fd}  non è un file descriptor.
  \item[\errcode{EINVAL}] \param{fd} è un riferimento ad un socket, non a un
    file o non è aperto in scrittura.
  \end{errlist}
  per \func{truncate} si hanno:
  \begin{errlist}
  \item[\errcode{EACCES}] il file non ha permesso di scrittura o non si ha il
    permesso di esecuzione una delle directory del \itindex{pathname}
    \textit{pathname}.
  \item[\errcode{ETXTBSY}] il file è un programma in esecuzione.
  \end{errlist}
  ed anche \errval{ENOTDIR}, \errval{ENAMETOOLONG}, \errval{ENOENT},
  \errval{EROFS}, \errval{EIO}, \errval{EFAULT}, \errval{ELOOP}.}
\end{functions}

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 il pathname \param{file\_name} per
\func{truncate} e con il file descriptor \param{fd} per \funcd{ftruncate}; se
il file è più lungo della lunghezza specificata i dati in eccesso saranno
perduti.

Il comportamento in caso di lunghezza inferiore non è specificato e dipende
dall'implementazione: il file può essere lasciato invariato o esteso fino alla
lunghezza scelta; 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, questi sono registrati
\itindex{inode} nell'\textit{inode} insieme agli altri attributi del file e
possono essere letti tramite la funzione \func{stat}, che li restituisce
attraverso tre specifici campi della struttura \struct{stat} di
fig.~\ref{fig:file_stat_struct}. Il significato di detti tempi e dei relativi
campi è riportato nello schema in tab.~\ref{tab:file_file_times}, dove è anche
riportato un esempio delle funzioni che effettuano cambiamenti su di essi. Il
valore è 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}, \var{st\_mtime}) e il tempo di
ultimo cambiamento di stato (il \textit{change time}, \var{st\_ctime}). Il
primo infatti fa riferimento ad una modifica del contenuto di un file, mentre
il secondo ad una modifica \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 o
(talvolta insieme anche al tempo di cambiamento di stato) per decidere quali
file devono essere archiviati per il backup. 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 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}.

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 cicli di riscrittura per i dischi su memorie riscrivibili.

Per questo motivo, onde evitare di mantenere una informazione che nella
maggior parte dei casi non interessa, è sempre stato possibile disabilitare
l'aggiornamento del tempo di ultimo accesso con l'opzione di montaggio
\texttt{noatime}. Dato però che questo può creare problemi a qualche
programma, in Linux è stata introdotta la opzione \texttt{relatime} che esegue
l'aggiornamento soltanto se il tempo di ultimo accesso è precedente al tempo di
ultima modifica o cambiamento, così da 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, e ad esempio i programmi
citati in precedenza continuano a funzionare. Questa opzione, a partire dal
kernel 2.6.30, è diventata il comportamento di default e non deve più essere
specificata esplicitamente.\footnote{si può comunque riottenere il vecchio
  comportamento usando la opzione di montaggio \texttt{strictatime}.}

\begin{table}[htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|c|c|c|c|c|c|l|}
    \hline
    \multicolumn{1}{|p{3cm}|}{\centering{\vspace{6pt}\textbf{Funzione}}} &
    \multicolumn{3}{|p{3.6cm}|}{\centering{
        \textbf{File o directory del riferimento}}}&
    \multicolumn{3}{|p{3.6cm}|}{\centering{
        \textbf{Directory contenente il riferimento}}} 
    &\multicolumn{1}{|p{3.6cm}|}{\centering{\vspace{6pt}\textbf{Note}}} \\
    \cline{2-7}
    \cline{2-7}
    \multicolumn{1}{|p{3cm}|}{} 
    &\multicolumn{1}{|p{.9cm}|}{\centering{\textsl{(a)}}}
    &\multicolumn{1}{|p{.9cm}|}{\centering{\textsl{(m)}}}
    &\multicolumn{1}{|p{.9cm}|}{\centering{\textsl{(c)}}}
    &\multicolumn{1}{|p{.9cm}|}{\centering{\textsl{(a)}}}
    &\multicolumn{1}{|p{.9cm}|}{\centering{\textsl{(m)}}}
    &\multicolumn{1}{|p{.9cm}|}{\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{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{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
    \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 se si tiene conto di quanto
già detto, 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 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 noti infine come \var{st\_ctime} non abbia nulla a che fare con il tempo di
creazione del file, usato in molti altri sistemi operativi, ma che in Unix non
esiste. Per questo motivo 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 come data di ultima modifica.

I tempi di ultimo accesso e modifica possono essere modificati esplicitamente
usando la funzione \funcd{utime}, il cui prototipo è:
\begin{prototype}{utime.h}
  {int utime(const char *filename, struct utimbuf *times)} 
  Modifica i tempi di ultimo accesso e modifica di un file.

  \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}] non si ha il permesso di scrittura sul file.
    \item[\errcode{EPERM}] non si è proprietari del file.
    \end{errlist}
    ed inoltre \errval{EROFS} e \errval{ENOENT}.}
\end{prototype}

La funzione cambia i tempi di ultimo accesso e 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 e i privilegi necessari per eseguirla dipendono da
cosa è l'argomento \param{times}; se è \val{NULL} la funzione imposta il
tempo corrente ed è sufficiente avere accesso in scrittura al file; se invece
si è specificato un valore la funzione avrà successo solo se si è proprietari
del file o si hanno i privilegi di amministratore.

Si tenga presente che non è comunque possibile specificare 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} (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.

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 modifica, \funcd{utimes}, che consente di specificare tempi con maggior
precisione; il suo prototipo è:
\begin{prototype}
  {sys/time.h}
  {int utimes(const char *filename, struct timeval times[2])} 
  Modifica i tempi di ultimo accesso e modifica di un file.

  \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}] non si ha il permesso di scrittura sul file.
    \item[\errcode{EPERM}] non si è proprietari del file.
    \end{errlist} 
    ed inoltre \errval{EROFS} e \errval{ENOENT}.}
\end{prototype}

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 link simbolico. I relativi
prototipi sono:
\begin{functions}
  \headdecl{sys/time.h} 
  
  \funcdecl{int futimes(int fd, const struct timeval tv[2])} Cambia i tempi
  di un file già aperto specificato tramite il file descriptor \param{fd}.

  \funcdecl{int lutimes(const char *filename, const struct timeval tv[2])}
  Cambia i tempi di \param{filename} anche se questo è un link simbolico.
  
  
  \bodydesc{Le funzioni restituiscono zero in caso di successo e $-1$ per un
    errore, nel qual caso \var{errno} assumerà 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{functions}

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 facendo riferimento al relativo file
descriptor mentre con \func{lutimes} nel caso in cui \param{filename} sia un
link 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{functions}
  \headdecl{sys/time.h} 
  
  \funcdecl{futimens(int fd, const struct timespec times[2])} Cambia i tempi
  di un file già aperto, specificato dal file descriptor \param{fd}.

  \funcdecl{int utimensat(int dirfd, const char *pathname, const struct
    timespec times[2], int flags)} Cambia i tempi del file \param{pathname}.
  
  
  \bodydesc{Le funzioni restituiscono zero in caso di successo e $-1$ per un
    errore, nel qual caso \var{errno} assumerà 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{functions}

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 in una recente revisione
dello standard POSIX (la POSIX.1-2008); sono state introdotte a partire dal
kernel 2.6.22, e supportate dalle \acr{glibc} a partire dalla versione
2.6.\footnote{in precedenza, a partire dal kernel 2.6.16, era stata introdotta
  la funzione \func{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
\textit{pathname relativi} specificando la directory da usare come riferimento
in \param{dirfd} e la possibilità di usare \param{flags} per indicare alla
funzione di dereferenziare o meno i link 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 (\acr{uid} e \acr{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 \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
\cmd{u} (per \textit{user}), \cmd{g} (per \textit{group}) e \cmd{o} (per
\textit{other}), inoltre se si vuole indicare tutti i raggruppamenti insieme
si usa la lettera \cmd{a} (per \textit{all}). Si tenga ben presente questa
distinzione dato che in certi casi, mutuando la terminologia in uso nel VMS,
si parla dei permessi base come di permessi per \textit{owner}, \textit{group}
ed \textit{all}, le cui iniziali possono dar luogo a confusione.  Le costanti
che permettono di accedere al valore numerico di questi bit nel campo
\var{st\_mode} sono riportate in 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 link 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
\itindex{pathname} \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 \itindex{pathname}
\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 link simbolico sono ignorati, contano quelli del file a cui
fa riferimento; per questo in genere il comando \cmd{ls} riporta per un link
simbolico tutti i permessi come concessi; utente e gruppo a cui esso
appartiene vengono pure ignorati quando il link viene risolto, vengono
controllati solo quando viene richiesta la rimozione del link 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'\acr{uid} effettivo, il \acr{gid}
effettivo e gli eventuali \acr{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'\acr{uid} effettivo e il \acr{gid} effettivo
corrispondono ai valori dell'\acr{uid} e del \acr{gid} dell'utente che ha
lanciato il processo, mentre i \acr{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'\acr{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'\acr{uid} effettivo del processo è uguale all'\acr{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 \acr{gid} effettivo del processo o uno dei \acr{gid} supplementari
  dei processi corrispondono al \acr{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 \acr{uid} effettivo al nuovo processo l'\acr{uid} del
proprietario del file al posto dell'\acr{uid} del processo originario.  Avere
il bit \acr{sgid} impostato ha lo stesso effetto sul \acr{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'\acr{uid} ed il \acr{gid} effettivo del processo;
ci sono casi però in cui si può voler effettuare il controllo con l'\acr{uid}
reale ed il \acr{gid} reale, vale a dire usando i valori di \acr{uid} e
\acr{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{prototype}{unistd.h}
{int access(const char *pathname, int mode)}

Verifica i permessi di accesso.
  
\bodydesc{La funzione ritorna 0 se l'accesso è consentito, -1 se l'accesso non
  è consentito ed in caso di errore; nel qual caso la variabile \var{errno}
  assumerà i 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}.}
\end{prototype}

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 link 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{functions}
  \headdecl{sys/types.h} 
  \headdecl{sys/stat.h} 
  
  \funcdecl{int chmod(const char *path, mode\_t mode)} Cambia i permessi del
  file indicato da \param{path} al valore indicato da \param{mode}.
  
  \funcdecl{int fchmod(int fd, mode\_t mode)} Analoga alla precedente, ma usa
  il file descriptor \param{fd} per indicare il file.
  
  \bodydesc{Le funzioni restituiscono 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'\acr{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 \errval{EIO}; \func{chmod} restituisce anche \errval{EFAULT},
  \errval{ENAMETOOLONG}, \errval{ENOENT}, \errval{ENOMEM}, \errval{ENOTDIR},
  \errval{EACCES}, \errval{ELOOP}; \func{fchmod} anche \errval{EBADF}.}
\end{functions}

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'\acr{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'\acr{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'\acr{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
  \struct{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{prototype}{stat.h}
{mode\_t umask(mode\_t mask)}

Imposta la maschera dei permessi dei bit al valore specificato da \param{mask}
(di cui vengono presi solo i 9 bit meno significativi).
  
  \bodydesc{La funzione ritorna il precedente valore della maschera. È una
    delle poche funzioni che non restituisce codici di errore.}
\end{prototype}

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'\acr{uid} del nuovo file corrisponda
all'\acr{uid} effettivo del processo che lo crea; per il \acr{gid} invece prevede
due diverse possibilità:
\begin{itemize*}
\item il \acr{gid} del file corrisponde al \acr{gid} effettivo del processo.
\item il \acr{gid} del file corrisponde al \acr{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
\acr{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 \acr{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 \acr{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{functions}
  \headdecl{sys/types.h} 
  \headdecl{sys/stat.h} 
  
  \funcdecl{int chown(const char *path, uid\_t owner, gid\_t group)}
  \funcdecl{int fchown(int fd, uid\_t owner, gid\_t group)}
  \funcdecl{int lchown(const char *path, uid\_t owner, gid\_t group)}

  Le funzioni cambiano utente e gruppo di appartenenza di un file ai valori
  specificati dalle variabili \param{owner} e \param{group}. 
  
  \bodydesc{Le funzioni restituiscono 0 in caso di successo e -1 per un
    errore, nel qual caso caso \var{errno} assumerà i valori:
  \begin{errlist}
  \item[\errcode{EPERM}] l'\acr{uid} effettivo non corrisponde a quello del
    proprietario del file o non è zero, o utente e gruppo non sono validi
  \end{errlist}
  Oltre a questi entrambe restituiscono gli errori \errval{EROFS} e
  \errval{EIO}; \func{chown} restituisce anche \errval{EFAULT},
  \errval{ENAMETOOLONG}, \errval{ENOENT}, \errval{ENOMEM}, \errval{ENOTDIR},
  \errval{EACCES}, \errval{ELOOP}; \func{fchown} anche \errval{EBADF}.}
\end{functions}

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 link simbolici, per operare direttamente su
un link simbolico si deve usare la funzione \func{lchown}.\footnote{fino alla
  versione 2.1.81 in Linux \func{chown} non seguiva i link simbolici, da
  allora questo comportamento è stato assegnato alla funzione \func{lchown},
  introdotta per l'occasione, ed è stata creata una nuova system call per
  \func{chown} che seguisse i link simbolici.} La funzione \func{fchown} opera
su un file aperto, essa è 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}
    \acr{s}&\acr{s}&\acr{t}&r&w&x&r&w&x&r&w&x& \\
    \hline
    \hline
   1&-&-&-&-&-&-&-&-&-&-&-&Se eseguito ha i permessi del proprietario.\\
   -&1&-&-&-&1&-&-&-&-&-&-&Se eseguito ha i permessi del gruppo proprietario.\\
   -&1&-&-&-&0&-&-&-&-&-&-&Il \itindex{mandatory~locking} 
                           \textit{mandatory locking} è abilitato.\\
   -&-&1&-&-&-&-&-&-&-&-&-&Non utilizzato.\\
   -&-&-&1&-&-&-&-&-&-&-&-&Permesso di lettura per il proprietario.\\
   -&-&-&-&1&-&-&-&-&-&-&-&Permesso di scrittura per il proprietario.\\
   -&-&-&-&-&1&-&-&-&-&-&-&Permesso di esecuzione per il proprietario.\\
   -&-&-&-&-&-&1&-&-&-&-&-&Permesso di lettura per il gruppo proprietario.\\
   -&-&-&-&-&-&-&1&-&-&-&-&Permesso di scrittura per il gruppo proprietario.\\
   -&-&-&-&-&-&-&-&1&-&-&-&Permesso di esecuzione per il gruppo proprietario.\\
   -&-&-&-&-&-&-&-&-&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}
    \acr{s}&\acr{s}&\acr{t}&r&w&x&r&w&x&r&w&x& \\
    \hline
    \hline
    1&-&-&-&-&-&-&-&-&-&-&-&Non utilizzato.\\
    -&1&-&-&-&-&-&-&-&-&-&-&Propaga il gruppo proprietario ai nuovi file 
                            creati.\\
    -&-&1&-&-&-&-&-&-&-&-&-&Limita l'accesso in scrittura dei file nella 
                            directory.\\
    -&-&-&1&-&-&-&-&-&-&-&-&Permesso di visualizzazione per il proprietario.\\
    -&-&-&-&1&-&-&-&-&-&-&-&Permesso di aggiornamento per il proprietario.\\
    -&-&-&-&-&1&-&-&-&-&-&-&Permesso di attraversamento per il proprietario.\\
    -&-&-&-&-&-&1&-&-&-&-&-&Permesso di visualizzazione per il gruppo 
                            proprietario.\\
    -&-&-&-&-&-&-&1&-&-&-&-&Permesso di aggiornamento per il gruppo 
                            proprietario.\\
    -&-&-&-&-&-&-&-&1&-&-&-&Permesso di attraversamento per il gruppo 
                            proprietario.\\
    -&-&-&-&-&-&-&-&-&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 link
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 \index{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} \index{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 \index{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 link 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 link 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 link 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 \index{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 delle \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 link
simbolico e ad un file descriptor; i rispettivi prototipi sono:
\begin{functions}
  \headdecl{sys/types.h} 
  \headdecl{attr/xattr.h} 
  
  \funcdecl{ssize\_t getxattr(const char *path, const char *name, void
    *value, size\_t size)} 

  \funcdecl{ssize\_t lgetxattr(const char *path, const char *name, void
    *value, size\_t size)} 

  \funcdecl{ssize\_t fgetxattr(int filedes, const char *name, void *value,
    size\_t size)}

  Le funzioni leggono il valore di un attributo esteso.
  
  \bodydesc{Le funzioni restituiscono un intero positivo che indica la
    dimensione dell'attributo richiesto in caso di successo, e $-1$ in caso di
    errore, nel qual caso \var{errno} assumerà i 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}
  e tutti gli errori di \func{stat}, come \errcode{EPERM} se non si hanno i
  permessi di accesso all'attributo. }
\end{functions}

Le funzioni \func{getxattr} e \func{lgetxattr} prendono come primo argomento
un pathname che indica il file di cui si vuole richiedere un attributo, la
sola differenza è che la seconda, se il pathname indica un link 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
link simbolico o specificando un file descriptor; i loro prototipi sono:
\begin{functions}
  \headdecl{sys/types.h} 
  \headdecl{attr/xattr.h} 
  
  \funcdecl{int setxattr(const char *path, const char *name, const void
    *value, size\_t size, int flags)}

  \funcdecl{int lsetxattr(const char *path, const char *name, const void
    *value, size\_t size, int flags)}

  \funcdecl{int fsetxattr(int filedes, const char *name, const void *value,
    size\_t size, int flags)}

  Impostano il valore di un attributo esteso.
  
  \bodydesc{Le funzioni restituiscono 0 in caso di successo, e $-1$ in caso di
    errore, nel qual caso \var{errno} assumerà i 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}
  Oltre a questi potranno essere restituiti tutti gli errori di \func{stat},
  ed in particolare \errcode{EPERM} se non si hanno i permessi di accesso
  all'attributo.  
}
\end{functions}

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{functions}
  \headdecl{sys/types.h} 
  \headdecl{attr/xattr.h} 
  
  \funcdecl{ssize\_t listxattr(const char *path, char *list, size\_t size)}

  \funcdecl{ssize\_t llistxattr(const char *path, char *list, size\_t size)}

  \funcdecl{ssize\_t flistxattr(int filedes, char *list, size\_t size)}

  Leggono la lista degli attributi estesi di un file.
  
  \bodydesc{Le funzioni restituiscono un intero positivo che indica la
    dimensione della lista in caso di successo, e $-1$ in caso di errore, nel
    qual caso \var{errno} assumerà i 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}
  Oltre a questi potranno essere restituiti tutti gli errori di \func{stat},
  ed in particolare \errcode{EPERM} se non si hanno i permessi di accesso
  all'attributo.  
}
\end{functions}

Come per le precedenti le tre funzioni leggono gli attributi rispettivamente
di un file, un link 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{functions}
  \headdecl{sys/types.h} 
  \headdecl{attr/xattr.h} 
  
  \funcdecl{int removexattr(const char *path, const char *name)}

  \funcdecl{int lremovexattr(const char *path, const char *name)}

  \funcdecl{int fremovexattr(int filedes, const char *name)}


  Rimuovono un attributo esteso di un file.
  
  \bodydesc{Le funzioni restituiscono 0 in caso di successo, e $-1$ in caso di
    errore, nel qual caso \var{errno} assumerà i 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 di \func{stat}.  
}
\end{functions}

Le tre funzioni rimuovono l'attributo esteso indicato dall'argomento
\param{name} rispettivamente di un file, un link 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 delle
\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 \index{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 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'\acr{uid} del processo è nullo l'accesso è sempre garantito senza
  nessun controllo.
\item Se l'\acr{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'\acr{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 \acr{gid} del processo o uno dei \acr{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 \acr{gid} del processo o uno dei \acr{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 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
                                   \acr{uid} e \acr{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 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 \func{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 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
\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 \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 \acr{uid} e \acr{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 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
                            \acr{uid} e \acr{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
                            \acr{uid} e \acr{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 \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 \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
                          \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 \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} 
                         (\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
\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 \acr{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 \acr{uid}
nullo a \acr{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 \acr{uid} effettivo nullo a non nullo
  l'\textit{effective set} del processo viene totalmente azzerato, se
  viceversa si passa da \acr{uid} effettivo non nullo a nullo il
  \textit{permitted set} viene copiato nell'\textit{effective set};
\item se si passa da \textit{file system} \acr{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 \acr{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
                                \acr{uid} passano ad un valore non
                                nullo (regola di compatibilità per il cambio
                                di \acr{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 \acr{uid}
                                dei gruppi \textit{effective} e
                                \textit{file system} (regole di compatibilità
                                per il cambio di \acr{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 \acr{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{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'\acr{uid} effettivo del
  processo (o meglio l'\acr{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:sys_file_config}), 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 \acr{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
\texttt{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 delle \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 \texttt{/usr/include/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
  \texttt{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,
\func{cap\_to\_name} e \func{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 \texttt{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 funzione \func{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.

Come accennato in sez.~\ref{sec:proc_fork} ogni processo oltre ad una
directory di lavoro, ha anche una directory \textsl{radice}\footnote{entrambe
  sono contenute in due campi (rispettivamente \var{pwd} e \var{root}) di
  \struct{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 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'\acr{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 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 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 DirScan direntry while current working home shell pwd get
% 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
% LocalWords:  multiplexing fsync fasync seek block superblock gapil tex img
% 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

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