\textsl{\code{create}} & Chiamata per creare un nuovo file (vedi
sez.~\ref{sec:file_open}).\\
\textsl{\code{link}} & Crea un \textit{hard link} (vedi
- sez.~\ref{sec:file_link}).\\
+ sez.~\ref{sec:link_symlink_rename}).\\
\textsl{\code{unlink}} & Cancella un \textit{hard link} (vedi
- sez.~\ref{sec:file_link}).\\
+ sez.~\ref{sec:link_symlink_rename}).\\
\textsl{\code{symlink}}& Crea un link simbolico (vedi
- sez.~\ref{sec:file_symlink}).\\
+ sez.~\ref{sec:link_symlink_rename}).\\
\textsl{\code{mkdir}} & Crea una directory (vedi
sez.~\ref{sec:file_dir_creat_rem}).\\
\textsl{\code{rmdir}} & Rimuove una directory (vedi
\textsl{\code{mknod}} & Crea un file speciale (vedi
sez.~\ref{sec:file_mknod}).\\
\textsl{\code{rename}} & Cambia il nome di un file (vedi
- sez.~\ref{sec:file_remove}).\\
+ sez.~\ref{sec:link_symlink_rename}).\\
\textsl{\code{lookup}}& Risolve il nome di un file.\\
\hline
\end{tabular}
\kstruct{inode} di fig.~\ref{fig:kstruct_inode}.} Solo quando questo
contatore si annulla i dati del file possono essere effettivamente rimossi
dal disco. Per questo la funzione per cancellare un file si chiama
- \func{unlink} (vedi sez.~\ref{sec:file_link}), ed in realtà non cancella
- affatto i dati del file, ma si limita ad eliminare la relativa voce da una
- directory e decrementare il numero di riferimenti nell'\textit{inode}.
+ \func{unlink} (vedi sez.~\ref{sec:link_symlink_rename}), ed in realtà non
+ cancella affatto i dati del file, ma si limita ad eliminare la relativa voce
+ da una directory e decrementare il numero di riferimenti
+ nell'\textit{inode}.
\item All'interno di ogni filesystem ogni \textit{inode} è identificato da un
numero univoco. Il numero di \textit{inode} associato ad una voce in una
che contiene riferimenti ad \textit{inode} relativi ad altri filesystem.
Questa è la ragione che limita l'uso del comando \cmd{ln}, che crea una
nuova voce per un file esistente con la funzione \func{link} (vedi
- sez.~\ref{sec:file_link}), a operare su file nel filesystem corrente.
+ sez.~\ref{sec:link_symlink_rename}), a operare su file nel filesystem
+ corrente.
\item Quando si cambia nome ad un file senza cambiare filesystem il contenuto
del file non viene spostato fisicamente, viene semplicemente creata una
nuova voce per l'\textit{inode} in questione e rimossa la precedente, questa
è la modalità in cui opera normalmente il comando \cmd{mv} attraverso la
- funzione \func{rename} (vedi sez.~\ref{sec:file_remove}). Questa operazione
- non modifica minimamente neanche l'\textit{inode} del file, dato che non si
- opera sul file ma sulla directory che lo contiene.
+ funzione \func{rename} (vedi sez.~\ref{sec:link_symlink_rename}). Questa
+ operazione non modifica minimamente neanche l'\textit{inode} del file, dato
+ che non si opera sul file ma sulla directory che lo contiene.
\item Gli \textit{inode} dei file, che contengono i \textsl{metadati}, ed i
blocchi di spazio disco, che contengono i dati, sono risorse indipendenti ed
\subsection{La gestione dell'uso dei filesystem}
-\label{sec:sys_file_config}
+\label{sec:filesystem_mounting}
Come accennato in sez.~\ref{sec:file_arch_overview} per poter accedere ai file
occorre rendere disponibile al sistema il filesystem su cui essi sono
memorizzati. L'operazione di attivazione del filesystem è chiamata
-\textsl{montaggio} e per far questo in Linux si usa la funzione \funcd{mount},
-il cui prototipo è:\footnote{la funzione è una versione specifica di Linux che
- usa la omonima \textit{system call} e non è portabile.}
+\textsl{montaggio} e per far questo in Linux si usa la funzione di sistema
+\funcd{mount}, il cui prototipo è:\footnote{la funzione è una versione
+ specifica di Linux che usa la omonima \textit{system call} e non è
+ portabile.}
\begin{funcproto}{
\fhead{sys/mount.h}
Il supporto per il \textit{bind mount} consente di superare i limiti
presenti per gli \textit{hard link} (di cui parleremo in
- sez.~\ref{sec:file_link}) con la possibilità di fare riferimento alla
- porzione dell'albero dei file di un filesystem presente a partire da una
- certa directory, utilizzando una qualunque altra directory, anche se questa
- sta su un filesystem diverso. Si può così fornire una alternativa all'uso
- dei link simbolici (di cui parleremo in sez.~\ref{sec:file_symlink}) che
- funziona correttamente anche all'intero di un \textit{chroot} (argomento su
- cui torneremo in sez.~\ref{sec:file_chroot}).
-\itindend{bind~mount}
+ sez.~\ref{sec:link_symlink_rename}) con la possibilità di fare riferimento
+ alla porzione dell'albero dei file di un filesystem presente a partire da
+ una certa directory, utilizzando una qualunque altra directory, anche se
+ questa sta su un filesystem diverso. Si può così fornire una alternativa
+ all'uso dei link simbolici (di cui parleremo in
+ sez.~\ref{sec:link_symlink_rename}) che funziona correttamente anche
+ all'intero di un \textit{chroot} (argomento su cui torneremo in
+ sez.~\ref{sec:file_chroot}). \itindend{bind~mount}
\item[\const{MS\_DIRSYNC}] Richiede che ogni modifica al contenuto di una
directory venga immediatamente registrata su disco in maniera sincrona
Una volta che non si voglia più utilizzare un certo filesystem è possibile
-``\textsl{smontarlo}'' usando la funzione \funcd{umount}, il cui prototipo è:
+``\textsl{smontarlo}'' usando la funzione di sistema \funcd{umount}, il cui
+prototipo è:
\begin{funcproto}{
\fhead{sys/mount.h}
directory di lavoro di un qualunque processo o il \itindex{mount~point}
\textit{mount point} di un altro filesystem.
-Linux provvede inoltre una seconda funzione, \funcd{umount2}, che consente un
-maggior controllo delle operazioni, come forzare lo smontaggio di un
-filesystem anche quando questo risulti occupato; il suo prototipo è:
+Linux provvede inoltre una seconda funzione di sistema, \funcd{umount2}, che
+consente un maggior controllo delle operazioni, come forzare lo smontaggio di
+un filesystem anche quando questo risulti occupato; il suo prototipo è:
\begin{funcproto}{
\fhead{sys/mount.h}
del filesystem questo venga smontato (presente dal
kernel 2.6.8 e dalla \acr{glibc} 2.11).\\
\const{UMOUNT\_NOFOLLOW}& non dereferenzia \param{target} se questo è un
- link simbolico (vedi sez.~\ref{sec:file_symlink})
- evitando problemi di sicurezza (presente dal kernel
- 2.6.34).\\
+ link simbolico (vedi
+ sez.~\ref{sec:link_symlink_rename}) evitando
+ problemi di sicurezza (presente dal kernel 2.6.34).\\
\hline
\end{tabular}
\caption{Costanti che identificano i bit dell'argomento \param{flags}
per un certo periodo di tempo.
Infine il flag \const{UMOUNT\_NOFOLLOW} non dereferenzia \param{target} se
-questo è un link simbolico (vedi sez.~\ref{sec:file_symlink}). Questa è una
-misura di sicurezza introdotta per evitare, per quei filesystem per il quale è
-prevista una gestione diretta da parte degli utenti, come quelli basati su
-FUSE,\footnote{il \textit{Filesystem in USEr space} (FUSE) è una delle più
- interessanti applicazioni del \itindex{Virtual~File~System} VFS che
- consente, tramite un opportuno modulo, di implementarne le funzioni in
+questo è un link simbolico (vedi sez.~\ref{sec:link_symlink_rename}). Questa è
+una misura di sicurezza introdotta per evitare, per quei filesystem per il
+quale è prevista una gestione diretta da parte degli utenti, come quelli
+basati su FUSE,\footnote{il \textit{Filesystem in USEr space} (FUSE) è una
+ delle più interessanti applicazioni del \itindex{Virtual~File~System} VFS
+ che consente, tramite un opportuno modulo, di implementarne le funzioni in
\textit{user space}, così da rendere possibile l'implementazione di un
- qualunque filesytem (con applicazioni di grande interesse come il filesystem
+ qualunque filesystem (con applicazioni di grande interesse come il filesystem
cifrato \textit{encfs} o il filesystem di rete \textit{sshfs}) che possa
essere usato direttamente per conto degli utenti.} che si possano passare
ai programmi che effettuano lo smontaggio dei filesystem, che in genere sono
possibilità di smontare qualunque filesystem.
-Altre due funzioni specifiche di Linux,\footnote{esse si trovano anche su BSD,
- ma con una struttura diversa.} utili per ottenere in maniera diretta
-informazioni riguardo al filesystem su cui si trova un certo file, sono
-\funcd{statfs} e \funcd{fstatfs}, i cui prototipi sono:
+Altre due funzioni di sistema specifiche di Linux,\footnote{esse si trovano
+ anche su BSD, ma con una struttura diversa.} utili per ottenere in maniera
+diretta informazioni riguardo al filesystem su cui si trova un certo file,
+sono \funcd{statfs} e \funcd{fstatfs}, i cui prototipi sono:
\begin{funcproto}{
\fhead{sys/vfs.h}
\label{fig:sys_statfs}
\end{figure}
-Le \acr{glibc} provvedono infine una serie di funzioni per la gestione dei due
+La \acr{glibc} provvede infine una serie di funzioni per la gestione dei due
file \conffile{/etc/fstab}\footnote{più precisamente \funcm{setfsent},
\funcm{getfsent}, \funcm{getfsfile}, \funcm{getfsspec}, \funcm{endfsent}.}
ed \conffile{/etc/mtab}\footnote{più precisamente \funcm{setmntent},
una versione degli stessi contenuti (vale a dire l'elenco dei filesystem
montati) generata direttamente dal kernel, e quindi sempre disponibile e
sempre aggiornata. Per questo motivo tralasceremo la trattazione, di queste
-funzioni, rimandando al manuale delle \acr{glibc} \cite{GlibcMan} per la
+funzioni, rimandando al manuale della \acr{glibc} \cite{GlibcMan} per la
documentazione completa.
% TODO (bassa priorità) scrivere delle funzioni (getfsent e getmntent &C)
\section{La gestione di file e directory}
\label{sec:file_dir}
-Come già accennato in sez.~\ref{sec:file_filesystem} in un sistema unix-like
-la gestione dei file ha delle caratteristiche specifiche che derivano
-direttamente dall'architettura del sistema. In questa sezione esamineremo le
-funzioni usate per la manipolazione di file e directory, per la creazione di
-link simbolici e diretti, per la gestione e la lettura delle directory. In
-particolare ci soffermeremo sulle conseguenze che derivano dalla struttura
-generica di un qualunque filesystem illustrata in
-sez.~\ref{sec:file_filesystem} per quanto attiene il comportamento e gli
-effetti delle varie funzioni.
+In questa sezione esamineremo le funzioni usate per la manipolazione dei nomi
+file e directory, per la creazione di link simbolici e diretti, per la
+gestione e la lettura delle directory. In particolare ci soffermeremo sulle
+conseguenze che derivano dalla architettura di un filesystem unix-like
+illustrata in sez.~\ref{sec:file_filesystem} per quanto attiene il
+comportamento e gli effetti delle varie funzioni. Tratteremo infine la
+directory di lavoro e le funzioni per la gestione di file speciali e
+temporanei.
+
+
+\subsection{La gestione dei nomi dei file}
+\label{sec:link_symlink_rename}
-\subsection{Le funzioni \func{link} e \func{unlink}}
-\label{sec:file_link}
+% \subsection{Le funzioni \func{link} e \func{unlink}}
+% \label{sec:file_link}
Una caratteristica comune a diversi sistemi operativi è quella di poter creare
-dei nomi fittizi (come gli alias del vecchio MacOS o i collegamenti di Windows
-o i nomi logici del VMS) che permettono di fare riferimento allo stesso file
-chiamandolo con nomi diversi o accedendovi da directory diverse.
-
-Questo è possibile anche in ambiente Unix, dove tali collegamenti sono
-usualmente chiamati ``\textit{link}''; ma data l'architettura del sistema
-riguardo la gestione dei file ci sono due metodi sostanzialmente diversi per
-fare questa operazione.
-
-Come spiegato in sez.~\ref{sec:file_filesystem} l'accesso al contenuto di un
-file su disco avviene passando attraverso il suo \itindex{inode}
-\textit{inode}, che è la struttura usata dal kernel che lo identifica
-univocamente all'interno di un singolo filesystem. Il nome del file che si
-trova nella voce di una directory è solo un'etichetta, mantenuta all'interno
-della directory, che viene associata ad un puntatore che fa riferimento al
-suddetto \textit{inode}.
+dei nomi alternativi, come gli alias del vecchio MacOS o i collegamenti di
+Windows o i nomi logici del VMS, che permettono di fare riferimento allo
+stesso file chiamandolo con nomi diversi o accedendovi da directory diverse.
+Questo è possibile anche in ambiente Unix, dove un nome alternativo viene
+usualmente chiamato `` \textsl{collegamento}'' (o \textit{link}). Data
+l'architettura del sistema riguardo la gestione dei file vedremo però che ci
+sono due metodi sostanzialmente diversi per fare questa operazione.
+
+\itindbeg{hard~link}
+\index{collegamento!diretto|(}
+
+In sez.~\ref{sec:file_filesystem} abbiamo spiegato come la capacità di
+chiamare un file con nomi diversi sia connaturata con l'architettura di un
+filesystem per un sistema Unix, in quanto il nome del file che si trova in una
+directory è solo un'etichetta che viene associata ad un puntatore per ottenere
+il riferimento ad un \textit{inode}, ed è questa la struttura che il kernel
+usa per identifica univocamente gli oggetti su un filesystem.
Questo significa che fintanto che si resta sullo stesso filesystem la
-realizzazione di un link è immediata ed uno stesso file può avere tanti nomi
-diversi, dati da altrettante associazioni diverse allo stesso \itindex{inode}
-\textit{inode} effettuate tramite ``etichette'' diverse (voci, nella
-nomenclatura di sez.~\ref{sec:file_filesystem}) in directory diverse. Si noti
-anche che nessuno di questi nomi viene ad assumere una particolare preferenza
-o originalità rispetto agli altri, in quanto tutti fanno comunque riferimento
-allo stesso \itindex{inode} \textit{inode}.
-
-Per aggiungere ad una directory una voce che faccia riferimento ad un
-\itindex{inode} \textit{inode} già esistente si utilizza la funzione
-\funcd{link}, e si suole chiamare questo tipo di associazione un collegamento
-diretto, o \textit{hard link}. Il prototipo della funzione è il seguente:
+realizzazione di un collegamento è immediata ed uno stesso file può avere
+tanti nomi diversi, dati da altrettante associazioni diverse allo stesso
+\itindex{inode} \textit{inode} effettuate tramite ``etichette'' diverse in
+directory diverse. Si noti anche come nessuno di questi nomi possa assumere
+una particolare preferenza o originalità rispetto agli altri, in quanto tutti
+fanno comunque riferimento allo stesso \itindex{inode} \textit{inode} che è
+l'oggetto che identifica effettivamente il file.
+
+Quando si vuole aggiungere ad una directory una voce che faccia riferimento ad
+un file già esistente nella modalità appena descritta, per ottenere quello che
+viene denominato ``\textsl{collegamento diretto}'' (o \textit{hard link}), si
+deve usare la funzione di sistema \funcd{link}, il cui prototipo è:
\begin{funcproto}{
\fhead{unistd.h}
generico.}
\end{funcproto}
-
-La funzione crea sul \textit{pathname} \param{newpath} un collegamento diretto
-al file indicato da \param{oldpath}. Per quanto detto la creazione di un
-nuovo collegamento diretto non copia il contenuto del file, ma si limita a
-creare una voce nella directory specificata da \param{newpath} e ad aumentare
-di uno il numero di riferimenti al file (riportato nel campo \var{st\_nlink}
-della struttura \struct{stat}, vedi sez.~\ref{sec:file_stat}) aggiungendo il
-nuovo nome ai precedenti. In questo modo lo stesso file può essere chiamato
-con vari nomi in diverse directory.
+La funzione crea in \param{newpath} un collegamento diretto al file indicato
+da \param{oldpath}. Per quanto detto la creazione di un nuovo collegamento
+diretto non copia il contenuto del file, ma si limita a creare una voce
+specificata da \param{newpath} nella directory corrispondente e l'unica
+proprietà del file che verrà modificata sarà il numero di riferimenti al file
+(il campo \var{i\_nlink} della struttura \kstruct{inode}, vedi
+fig.~\ref{fig:kstruct_inode}) che verrà aumentato di di uno. In questo modo lo
+stesso file potrà essere acceduto sia con \param{newpath} che
+con \param{oldpath}.
Per quanto dicevamo in sez.~\ref{sec:file_filesystem} la creazione di un
collegamento diretto è possibile solo se entrambi i \textit{pathname} sono
-nello stesso filesystem. Inoltre il filesystem deve supportare i collegamenti
-diretti (il meccanismo non è disponibile ad esempio con il filesystem
-\acr{vfat} di Windows). In realtà la funzione ha un ulteriore requisito, e
-cioè che non solo che i due file siano sullo stesso filesystem, ma anche che
-si faccia riferimento ad essi sullo stesso \itindex{mount~point} \textit{mount
- point}.\footnote{si tenga presente infatti (vedi
- sez.~\ref{sec:sys_file_config}) che a partire dal kernel 2.4 uno stesso
+nello stesso filesystem ed inoltre esso deve supportare gli \textit{hard link}
+(il meccanismo non è disponibile ad esempio con il filesystem \acr{vfat} di
+Windows). In realtà la funzione ha un ulteriore requisito, e cioè che non solo
+che i due file siano sullo stesso filesystem, ma anche che si faccia
+riferimento ad essi all'interno dello stesso \itindex{mount~point}
+\textit{mount point}.\footnote{si tenga presente infatti, come detto in
+ sez.~\ref{sec:filesystem_mounting}, che a partire dal kernel 2.4 uno stesso
filesystem può essere montato più volte su directory diverse.}
La funzione inoltre opera sia sui file ordinari che sugli altri oggetti del
filesystem, con l'eccezione delle directory. In alcune versioni di Unix solo
l'amministratore è in grado di creare un collegamento diretto ad un'altra
directory: questo viene fatto perché con una tale operazione è possibile
-creare dei \textit{loop} nel filesystem (vedi l'esempio mostrato in
-sez.~\ref{sec:file_symlink}, dove riprenderemo il discorso) che molti
-programmi non sono in grado di gestire e la cui rimozione diventerebbe
-piuttosto complicata (in genere per questo tipo di errori occorre eseguire il
-programma \cmd{fsck} per riparare il filesystem).
+creare dei \textit{loop} nel filesystem (vedi fig.~\ref{fig:file_link_loop})
+che molti programmi non sono in grado di gestire e la cui rimozione
+diventerebbe piuttosto complicata (in genere per questo tipo di errori occorre
+eseguire il programma \cmd{fsck} per riparare il filesystem).
Data la pericolosità di questa operazione e la disponibilità dei link
-simbolici (che vedremo in sez.~\ref{sec:file_symlink}) e dei
-\itindex{bind~mount} \textit{bind mount} (già visti in
-sez.~\ref{sec:sys_file_config}) che possono fornire la stessa funzionalità
-senza questi problemi, nel caso di Linux questa capacità è stata completamente
-disabilitata, e al tentativo di creare un link diretto ad una directory la
-funzione \func{link} restituisce l'errore \errcode{EPERM}.
+simbolici (che vedremo a breve) e dei \itindex{bind~mount} \textit{bind mount}
+(già visti in sez.~\ref{sec:filesystem_mounting}) che possono fornire la
+stessa funzionalità senza questi problemi, nel caso di Linux questa capacità è
+stata completamente disabilitata, e al tentativo di creare un collegamento
+diretto ad una directory la funzione \func{link} restituisce sempre l'errore
+\errcode{EPERM}.
Un ulteriore comportamento peculiare di Linux è quello in cui si crea un
-\textit{hard link} ad un link simbolico. In questo caso lo standard
+\textit{hard link} ad un collegamento simbolico. In questo caso lo standard
POSIX.1-2001 prevederebbe che quest'ultimo venga risolto e che il collegamento
sia effettuato rispetto al file cui esso punta, e che venga riportato un
errore qualora questo non esista o non sia un file. Questo era anche il
ripristinato anche durante lo sviluppo della serie 2.1.x, per poi tornare al
comportamento attuale fino ad oggi (per riferimento si veda
\url{http://lwn.net/Articles/293902}).} è stato adottato un comportamento
-che non segue più lo standard per cui l'\textit{hard link} viene creato
-rispetto al link simbolico, e non al file cui questo punta. La revisione
-POSIX.1-2008 lascia invece il comportamento dipendente dall'implementazione,
-cosa che rende Linux aderente allo standard.
-
-La ragione di questa differenza rispetto al vecchio standard, presente anche
-in altri sistemi unix-like, sono dovute al fatto che un link simbolico può
-fare riferimento anche ad un file non esistente o a una directory, per i quali
-l'\textit{hard link} non può essere creato, per cui la scelta di seguire il
-link simbolico è stata ritenuta una scelta scorretta nella progettazione
-dell'interfaccia. Infatti se non ci fosse il comportamento adottato da Linux
-sarebbe impossibile creare un \textit{hard link} ad un link simbolico, perché
-la funzione lo risolverebbe e l'\textit{hard link} verrebbe creato verso la
-destinazione. Invece evitando di seguire lo standard l'operazione diventa
-possibile, ed anche il comportamento della funzione risulta molto più
-comprensibile. Tanto più che se proprio se si vuole creare un \textit{hard
- link} rispetto alla destinazione di un link simbolico è sempre possibile
-farlo direttamente.\footnote{ciò non toglie che questo comportamento possa
- causare problemi, come nell'esempio descritto nell'articolo citato nella
- nota precedente, a programmi che non si aspettano questa differenza rispetto
- allo standard POSIX.}
-
-La rimozione di un file (o più precisamente della voce che lo referenzia
-all'interno di una directory) si effettua con la funzione \funcd{unlink}; il
-suo prototipo è il seguente:
-
-\begin{funcproto}{
-\fhead{unistd.h}
-\fdecl{int unlink(const char *pathname)}
-\fdesc{Cancella un file.}
-}
-{La funzione ritorna $0$ in caso di successo e $-1$ per un errore,
- nel qual caso \var{errno} assumerà uno dei valori:
- \begin{errlist}
- \item[\errcode{EISDIR}] \param{pathname} si riferisce ad una
- directory.\footnotemark
- \item[\errcode{EROFS}] \param{pathname} è su un filesystem montato in sola
- lettura.
- \item[\errcode{EISDIR}] \param{pathname} fa riferimento a una directory.
- \end{errlist} ed inoltre \errval{EACCES}, \errval{EFAULT}, \errval{ENOENT},
- \errval{ENOTDIR}, \errval{ENOMEM}, \errval{EROFS}, \errval{ELOOP},
- \errval{EIO} nel loro significato generico.}
-\end{funcproto}
-
-\footnotetext{questo è un valore specifico ritornato da Linux che non consente
- l'uso di \func{unlink} con le directory (vedi sez.~\ref{sec:file_remove}).
- Non è conforme allo standard POSIX, che prescrive invece l'uso di
- \errcode{EPERM} in caso l'operazione non sia consentita o il processo non
- abbia privilegi sufficienti.}
-
-La funzione cancella il nome specificato da \param{pathname} nella relativa
-directory e decrementa il numero di riferimenti nel relativo \itindex{inode}
-\textit{inode}. Nel caso di link simbolico cancella il link simbolico; nel
-caso di socket, fifo o file di dispositivo \index{file!di~dispositivo} rimuove
-il nome, ma come per i file i processi che hanno aperto uno di questi oggetti
-possono continuare ad utilizzarlo.
-
-Per cancellare una voce in una directory è necessario avere il permesso di
-scrittura su di essa, dato che si va a rimuovere una voce dal suo contenuto, e
-il diritto di esecuzione sulla directory che la contiene (affronteremo in
-dettaglio l'argomento dei permessi di file e directory in
-sez.~\ref{sec:file_access_control}). Se inoltre lo \itindex{sticky~bit}
-\textit{sticky bit} (vedi sez.~\ref{sec:file_special_perm}) è impostato
-occorrerà anche essere proprietari del file o proprietari della directory (o
-root, per cui nessuna delle restrizioni è applicata).
-
-Una delle caratteristiche di queste funzioni è che la creazione/rimozione del
-nome dalla directory e l'incremento/decremento del numero di riferimenti
-\itindex{inode} nell'\textit{inode} devono essere effettuati in maniera
-atomica (si veda sez.~\ref{sec:proc_atom_oper}) senza possibili interruzioni
-fra le due operazioni. Per questo entrambe queste funzioni sono realizzate
-tramite una singola system call.
-
-Si ricordi infine che un file non viene eliminato dal disco fintanto che tutti
-i riferimenti ad esso sono stati cancellati: solo quando il \textit{link
- count} mantenuto \itindex{inode} nell'\textit{inode} diventa zero lo spazio
-occupato su disco viene rimosso (si ricordi comunque che a questo si aggiunge
-sempre un'ulteriore condizione,\footnote{come vedremo in
- cap.~\ref{cha:file_unix_interface} il kernel mantiene anche una tabella dei
- file aperti nei vari processi, che a sua volta contiene i riferimenti agli
- \itindex{inode} \textit{inode} ad essi relativi. Prima di procedere alla
- cancellazione dello spazio occupato su disco dal contenuto di un file il
- kernel controlla anche questa tabella, per verificare che anche in essa non
- ci sia più nessun riferimento all'\textit{inode} in questione.} e cioè che
-non ci siano processi che abbiano il suddetto file aperto).
-
-Questa proprietà viene spesso usata per essere sicuri di non lasciare file
-temporanei su disco in caso di crash dei programmi; la tecnica è quella di
-aprire il file e chiamare \func{unlink} subito dopo, in questo modo il
-contenuto del file è sempre disponibile all'interno del processo attraverso il
-suo file descriptor (vedi sez.~\ref{sec:file_fd}) fintanto che il processo non
-chiude il file, ma non ne resta traccia in nessuna directory, e lo spazio
-occupato su disco viene immediatamente rilasciato alla conclusione del
-processo (quando tutti i file vengono chiusi).
-
-
-\subsection{Le funzioni \func{remove} e \func{rename}}
-\label{sec:file_remove}
-
-Al contrario di quanto avviene con altri Unix, in Linux non è possibile usare
-\func{unlink} sulle directory; per cancellare una directory si può usare la
-funzione \func{rmdir} (vedi sez.~\ref{sec:file_dir_creat_rem}), oppure la
-funzione \funcd{remove}.
-
-Questa è la funzione prevista dallo standard ANSI C per cancellare un file o
-una directory (e funziona anche per i sistemi che non supportano i link
-diretti). Per i file è identica a \func{unlink} e per le directory è identica
-a \func{rmdir}; il suo prototipo è:
-
-\begin{funcproto}{
-\fhead{stdio.h}
-\fdecl{int remove(const char *pathname)}
-\fdesc{Cancella un nome dal filesystem.}
-}
-{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
- caso \var{errno} assumerà uno dei valori relativi alla chiamata utilizzata,
- pertanto si può fare riferimento a quanto illustrato nelle descrizioni di
- \func{unlink} e \func{rmdir}.}
-\end{funcproto}
-
-La funzione utilizza la funzione \func{unlink}\footnote{questo vale usando le
- \acr{glibc}; nelle libc4 e nelle libc5 la funzione \func{remove} è un
- semplice alias alla funzione \func{unlink} e quindi non può essere usata per
- le directory.} per cancellare i file e la funzione \func{rmdir} per
-cancellare le directory; si tenga presente che per alcune implementazioni del
-protocollo NFS utilizzare questa funzione può comportare la scomparsa di file
-ancora in uso.
-
-Per cambiare nome ad un file o a una directory (che devono comunque essere
-nello stesso filesystem) si usa invece la funzione \funcd{rename},\footnote{la
- funzione è definita dallo standard ANSI C, ma si applica solo per i file, lo
- standard POSIX estende la funzione anche alle directory.} il cui prototipo
-è:
-
-\begin{funcproto}{
-\fhead{stdio.h}
-\fdecl{int rename(const char *oldpath, const char *newpath)}
-\fdesc{Rinomina un file.}
-}
-{La funzione ritorna $0$ in caso di successo e $-1$ per un errore,
- nel qual caso \var{errno} assumerà uno dei valori:
- \begin{errlist}
- \item[\errcode{EISDIR}] \param{newpath} è una directory mentre
- \param{oldpath} non è una directory.
- \item[\errcode{EXDEV}] \param{oldpath} e \param{newpath} non sono sullo
- stesso filesystem.
- \item[\errcode{ENOTEMPTY}] \param{newpath} è una directory già esistente e
- non vuota.
- \item[\errcode{EBUSY}] o \param{oldpath} o \param{newpath} sono in uso da
- parte di qualche processo (come \index{directory~di~lavoro} directory di
- lavoro o come radice) o del sistema (come \itindex{mount~point}
- \textit{mount point}).
- \item[\errcode{EINVAL}] \param{newpath} contiene un prefisso di
- \param{oldpath} o più in generale si è cercato di creare una directory come
- sotto-directory di se stessa.
- \item[\errcode{ENOTDIR}] uno dei componenti dei \textit{pathname} non è una
- directory o \param{oldpath} è una directory e
- \param{newpath} esiste e non è una directory.
- \end{errlist} ed inoltre \errval{EACCES}, \errval{EPERM}, \errval{EMLINK},
- \errval{ENOENT}, \errval{ENOMEM}, \errval{EROFS}, \errval{ELOOP} e
- \errval{ENOSPC} nel loro significato generico.}
-\end{funcproto}
-
-La funzione rinomina il file \param{oldpath} in \param{newpath}, eseguendo se
-necessario lo spostamento di un file fra directory diverse. Eventuali altri
-link diretti allo stesso file non vengono influenzati.
-
-Il comportamento della funzione è diverso a seconda che si voglia rinominare
-un file o una directory; se ci riferisce ad un file allora \param{newpath}, se
-esiste, non deve essere una directory (altrimenti si ha l'errore
-\errcode{EISDIR}). Nel caso \param{newpath} indichi un file esistente questo
-viene cancellato e rimpiazzato (atomicamente).
+che non segue più lo standard per cui l'\textit{hard link} viene creato nei
+confronti del collegamento simbolico, e non del file cui questo punta. La
+revisione POSIX.1-2008 lascia invece il comportamento dipendente
+dall'implementazione, cosa che rende Linux aderente a questa versione
+successiva dello standard.
-Se \param{oldpath} è una directory allora \param{newpath}, se esiste, deve
-essere una directory vuota, altrimenti si avranno gli errori \errcode{ENOTDIR}
-(se non è una directory) o \errcode{ENOTEMPTY} (se non è vuota). Chiaramente
-\param{newpath} non può contenere \param{oldpath} altrimenti si avrà un errore
-\errcode{EINVAL}.
+\itindbeg{symbolic~link}
-Se \param{oldpath} si riferisce ad un link simbolico questo sarà rinominato; se
-\param{newpath} è un link simbolico verrà cancellato come qualunque altro
-file. Infine qualora \param{oldpath} e \param{newpath} siano due nomi dello
-stesso file lo standard POSIX prevede che la funzione non dia errore, e non
-faccia nulla, lasciando entrambi i nomi; Linux segue questo standard, anche
-se, come fatto notare dal manuale delle \textit{glibc}, il comportamento più
-ragionevole sarebbe quello di cancellare \param{oldpath}.
+\index{collegamento!simbolico|(}
-Il vantaggio nell'uso di questa funzione al posto della chiamata successiva di
-\func{link} e \func{unlink} è che l'operazione è eseguita atomicamente, non
-può esistere cioè nessun istante in cui un altro processo può trovare attivi
-entrambi i nomi dello stesso file, o, in caso di sostituzione di un file
-esistente, non trovare quest'ultimo prima che la sostituzione sia stata
-eseguita.
-
-In ogni caso se \param{newpath} esiste e l'operazione fallisce per un qualche
-motivo (come un crash del kernel), \func{rename} garantisce di lasciare
-presente un'istanza di \param{newpath}. Tuttavia nella sovrascrittura potrà
-esistere una finestra in cui sia \param{oldpath} che \param{newpath} fanno
-riferimento allo stesso file.
-
-
-\subsection{I link simbolici}
-\label{sec:file_symlink}
-
-Come abbiamo visto in sez.~\ref{sec:file_link} la funzione \func{link} crea
-riferimenti agli \itindex{inode} \textit{inode}, pertanto può funzionare
-soltanto per file che risiedono sullo stesso filesystem e solo per un
-filesystem di tipo Unix. Inoltre abbiamo visto che in Linux non è consentito
-eseguire un link diretto ad una directory.
-
-Per ovviare a queste limitazioni i sistemi Unix supportano un'altra forma di
-link (i cosiddetti \textit{soft link} o \textit{symbolic link}), che sono,
-come avviene in altri sistemi operativi, dei file speciali che contengono
-semplicemente il riferimento ad un altro file (o directory). In questo modo è
-possibile effettuare link anche attraverso filesystem diversi, a file posti in
-filesystem che non supportano i link diretti, a delle directory, ed anche a
-file che non esistono ancora.
-
-Il sistema funziona in quanto i link simbolici sono riconosciuti come tali dal
-kernel\footnote{è uno dei diversi tipi di file visti in
+La ragione di questa differenza rispetto al vecchio standard, presente anche
+in altri sistemi unix-like, sono dovute al fatto che un collegamento simbolico
+può fare riferimento anche ad un file non esistente o a una directory, per i
+quali l'\textit{hard link} non può essere creato, per cui la scelta di seguire
+il collegamento simbolico è stata ritenuta una scelta scorretta nella
+progettazione dell'interfaccia. Infatti se non ci fosse il comportamento
+adottato da Linux sarebbe impossibile creare un \textit{hard link} ad un
+collegamento simbolico, perché la funzione lo risolverebbe e l'\textit{hard
+ link} verrebbe creato verso la destinazione. Invece evitando di seguire lo
+standard l'operazione diventa possibile, ed anche il comportamento della
+funzione risulta molto più comprensibile. Tanto più che se proprio se si vuole
+creare un \textit{hard link} rispetto alla destinazione di un collegamento
+simbolico è sempre possibile farlo direttamente.\footnote{ciò non toglie che
+ questo comportamento possa causare problemi, come nell'esempio descritto
+ nell'articolo citato nella nota precedente, a programmi che non si aspettano
+ questa differenza rispetto allo standard POSIX.}
+
+Dato che \func{link} crea semplicemente dei nomi che fanno riferimenti agli
+\itindex{inode} \textit{inode}, essa può funzionare soltanto per file che
+risiedono sullo stesso filesystem e solo per un filesystem di tipo Unix.
+Inoltre abbiamo visto che in Linux non è consentito eseguire un collegamento
+diretto ad una directory.
+
+Per ovviare a queste limitazioni, come accennato all'inizio, i sistemi
+unix-like supportano un'altra forma di collegamento, detta
+``\textsl{collegamento simbolico}'' (o anche \textit{soft link} o
+\textit{symbolic link}). In questo caso si tratta, come avviene in altri
+sistemi operativi, di file speciali che contengono semplicemente il
+riferimento ad un altro file (o directory). In questo modo è possibile
+effettuare collegamenti anche attraverso filesystem diversi, a file posti in
+filesystem che non supportano i collegamenti diretti, a delle directory, ed
+anche a file che non esistono ancora.
+
+\itindend{hard~link}
+\index{collegamento!diretto|)}
+
+Il meccanismo funziona in quanto i \textit{symbolic link} sono riconosciuti
+come tali dal kernel\footnote{è uno dei diversi tipi di file visti in
tab.~\ref{tab:file_file_types}, contrassegnato come tale
nell'\textit{inode}, e riconoscibile dal valore del campo \var{st\_mode}
- della struttura \struct{stat} (vedi sez.~\ref{sec:file_stat}).} per cui
-alcune funzioni di libreria (come \func{open} o \func{stat}) quando ricevono
-come argomento un link simbolico vengono automaticamente applicate al file da
-esso specificato. La funzione che permette di creare un nuovo link simbolico
-è \funcd{symlink}, ed il suo prototipo è:
-
+ della struttura \struct{stat} (vedi sez.~\ref{sec:file_stat}).} e tutta una
+serie di funzioni di sistema (come \func{open} o \func{stat}) quando ricevono
+come argomento il \textit{pathname} di un collegamento simbolico vanno
+automaticamente ad operare sul file da esso specificato. La funzione di
+sistema che permette di creare un nuovo collegamento simbolico è
+\funcd{symlink}, ed il suo prototipo è:
\begin{funcproto}{
\fhead{unistd.h}
\fdecl{int symlink(const char *oldpath, const char *newpath)}
-\fdesc{Crea un nuovo link simbolico.}
+\fdesc{Crea un nuovo collegamento simbolico (\textit{symbolic link}).}
}
{La funzione ritorna $0$ in caso di successo e $-1$ per un errore,
nel qual caso \var{errno} assumerà uno dei valori:
\begin{errlist}
- \item[\errcode{EPERM}] il filesystem che contiene \param{newpath} non
- supporta i link simbolici.
+ \item[\errcode{EEXIST}] esiste già un file \param{newpath}.
\item[\errcode{ENOENT}] una componente di \param{newpath} non esiste o
\param{oldpath} è una stringa vuota.
- \item[\errcode{EEXIST}] esiste già un file \param{newpath}.
+ \item[\errcode{EPERM}] il filesystem che contiene \param{newpath} non
+ supporta i collegamenti simbolici.
\item[\errcode{EROFS}] \param{newpath} è su un filesystem montato in sola
lettura.
- \end{errlist} ed inoltre \errval{EFAULT}, \errval{EACCES},
- \errval{ENAMETOOLONG}, \errval{ENOTDIR}, \errval{ENOMEM}, \errval{ELOOP},
- \errval{ENOSPC} e \errval{EIO} nel loro significato generico.}
+ \end{errlist} ed inoltre \errval{EACCES}, \errval{EFAULT}, \errval{EIO},
+ \errval{ELOOP}, \errval{ENAMETOOLONG}, \errval{ENOMEM}, \errval{ENOSPC} e
+ \errval{ENOTDIR} nel loro significato generico.}
\end{funcproto}
-La funzione crea un nuovo link simbolico con \textit{pathname} \param{newpath}
-che fa riferimento ad \param{oldpath}. Si tenga presente che la funzione non
+La funzione crea un nuovo collegamento simbolico \param{newpath} che fa
+riferimento ad \param{oldpath}. Si tenga presente che la funzione non
effettua nessun controllo sull'esistenza di un file di nome \param{oldpath},
-ma si limita ad inserire il \textit{pathname} nel link simbolico. Pertanto un
-link simbolico può anche riferirsi ad un file che non esiste: in questo caso
-si ha quello che viene chiamato un \textit{dangling link}, letteralmente un
-\textsl{link ciondolante}.
-
-Come accennato i link simbolici sono risolti automaticamente dal kernel
-all'invocazione delle varie system call; in tab.~\ref{tab:file_symb_effect} si
-è riportato un elenco dei comportamenti delle varie funzioni di libreria che
-operano sui file nei confronti della risoluzione dei link simbolici,
-specificando quali seguono il link simbolico e quali invece possono operare
-direttamente sul suo contenuto.
+ma si limita ad inserire il \textit{pathname} nel collegamento
+simbolico. Pertanto un collegamento simbolico può anche riferirsi ad un file
+che non esiste ed in questo caso si ha quello che viene chiamato un
+\itindex{dangling~link} \textit{dangling link}, letteralmente un
+\index{collegamento!ciondolante} ``\textsl{collegamento ciondolante}''.
+
+Come accennato i collegamenti simbolici sono risolti automaticamente dal
+kernel all'invocazione delle varie \textit{system call}. In
+tab.~\ref{tab:file_symb_effect} si è riportato un elenco dei comportamenti
+delle varie funzioni di sistema che operano sui file nei confronti della
+risoluzione dei collegamenti simbolici, specificando quali li seguono e quali
+invece possono operare direttamente sui loro contenuti.
\begin{table}[htb]
\centering
\footnotesize
\func{unlink} & -- & $\bullet$ \\
\hline
\end{tabular}
- \caption{Uso dei link simbolici da parte di alcune funzioni.}
+ \caption{Uso dei collegamenti simbolici da parte di alcune funzioni.}
\label{tab:file_symb_effect}
\end{table}
\footnotetext{a partire dalla serie 2.0, e contrariamente a quanto indicato
- dallo standard POSIX, si veda quanto detto in sez.~\ref{sec:file_link}.}
+ dallo standard POSIX.1-2001.}
Si noti che non si è specificato il comportamento delle funzioni che operano
con i file descriptor, in quanto la risoluzione del link simbolico viene in
operazioni seguenti fanno riferimento solo a quest'ultimo.
Dato che, come indicato in tab.~\ref{tab:file_symb_effect}, funzioni come la
-\func{open} seguono i link simbolici, occorrono funzioni apposite per accedere
-alle informazioni del link invece che a quelle del file a cui esso fa
-riferimento. Quando si vuole leggere il contenuto di un link simbolico si usa
-la funzione \funcd{readlink}, il cui prototipo è:
-\begin{prototype}{unistd.h}
-{int readlink(const char *path, char *buff, size\_t size)}
- Legge il contenuto del link simbolico indicato da \param{path} nel buffer
- \param{buff} di dimensione \param{size}.
-
- \bodydesc{La funzione restituisce il numero di caratteri letti dentro
- \param{buff} o -1 per un errore, nel qual caso la variabile
- \var{errno} assumerà i valori:
+\func{open} seguono i collegamenti simbolici, occorrono funzioni apposite per
+accedere alle informazioni del collegamento invece che a quelle del file a cui
+esso fa riferimento. Quando si vuole leggere il contenuto di un collegamento
+simbolico si usa la funzione di sistema \funcd{readlink}, il cui prototipo è:
+
+\begin{funcproto}{
+\fhead{unistd.h}
+\fdecl{int readlink(const char *path, char *buff, size\_t size)}
+\fdesc{Legge il contenuto di un collegamento simbolico.}
+}
+{La funzione ritorna il numero di caratteri letti dentro \param{buff} in caso
+ di successo e $-1$ per un errore, nel qual caso \var{errno} assumerà uno
+ dei valori:
\begin{errlist}
\item[\errcode{EINVAL}] \param{path} non è un link simbolico o \param{size}
non è positiva.
- \end{errlist}
- ed inoltre \errval{ENOTDIR}, \errval{ENAMETOOLONG}, \errval{ENOENT},
- \errval{EACCES}, \errval{ELOOP}, \errval{EIO}, \errval{EFAULT} e
- \errval{ENOMEM}.}
-\end{prototype}
+ \end{errlist} ed inoltre \errval{EACCES}, \errval{EFAULT}, \errval{EIO},
+ \errval{ELOOP}, \errval{ENAMETOOLONG}, \errval{ENOENT}, \errval{ENOMEM} e
+ \errval{ENOTDIR} nel loro significato generico.}
+\end{funcproto}
-La funzione apre il link simbolico, ne legge il contenuto, lo scrive nel
-buffer, e lo richiude. Si tenga presente che la funzione non termina la
-stringa con un carattere nullo e la tronca alla dimensione specificata da
-\param{size} per evitare di sovrascrivere oltre le dimensioni del buffer.
+La funzione legge il \textit{pathname} a cui fa riferimento il collegamento
+simbolico indicato dall'argomento \param{path} scrivendolo sul
+buffer \param{buff} di dimensione \param{size}. Si tenga presente che la
+funzione non termina la stringa con un carattere nullo e che se questa è
+troppo lunga la tronca alla dimensione specificata da \param{size} per evitare
+di sovrascrivere oltre le dimensioni del buffer.
\begin{figure}[htb]
\centering
\includegraphics[width=8.5cm]{img/link_loop}
- \caption{Esempio di loop nel filesystem creato con un link simbolico.}
+ \caption{Esempio di loop nel filesystem creato con un collegamento
+ simbolico.}
\label{fig:file_link_loop}
\end{figure}
-Un caso comune che si può avere con i link simbolici è la creazione dei
-cosiddetti \textit{loop}. La situazione è illustrata in
-fig.~\ref{fig:file_link_loop}, che riporta la struttura della directory
-\file{/boot}. Come si vede si è creato al suo interno un link simbolico che
-punta di nuovo a \file{/boot}.\footnote{il loop mostrato in
- fig.~\ref{fig:file_link_loop} è un usato per poter permettere a \cmd{grub}
- (un bootloader in grado di leggere direttamente da vari filesystem il file
- da lanciare come sistema operativo) di vedere i file contenuti nella
- directory \file{/boot} con lo stesso \textit{pathname} con cui verrebbero
- visti dal sistema operativo, anche se essi si trovano, come accade spesso,
- su una partizione separata (che \cmd{grub}, all'avvio, vede come radice).}
+Come accennato uno dei motivi per cui non sono consentiti \textit{hard link}
+alle directory è che questi possono creare dei \textit{loop} nella risoluzione
+dei nomi che non possono essere eliminati facilmente. Invece è sempre
+possibile, ed in genere anche molto utile, creare un collegamento simbolico ad
+una directory, anche se in questo caso si potranno ottenere anche dei
+\textit{loop}. La situazione è illustrata in fig.~\ref{fig:file_link_loop},
+che riporta la struttura della directory \file{/boot}. Come si vede si è
+creato al suo interno un collegamento simbolico che punta di nuovo a
+\file{/boot}.\footnote{il loop mostrato in fig.~\ref{fig:file_link_loop} è un
+ usato per poter permettere a \cmd{grub} (un bootloader in grado di leggere
+ direttamente da vari filesystem il file da lanciare come sistema operativo)
+ di vedere i file contenuti nella directory \file{/boot} con lo stesso
+ \textit{pathname} con cui verrebbero visti dal sistema operativo, anche se
+ essi si trovano, come accade spesso, su una partizione separata (che
+ \cmd{grub}, all'avvio, vede come radice).}
Questo può causare problemi per tutti quei programmi che effettuano la
-scansione di una directory senza tener conto dei link simbolici, ad esempio se
-lanciassimo un comando del tipo \code{grep -r linux *}, il loop nella
-directory porterebbe il comando ad esaminare \file{/boot}, \file{/boot/boot},
-\file{/boot/boot/boot} e così via.
+scansione di una directory senza tener conto dei collegamenti simbolici, ad
+esempio se lanciassimo un comando del tipo \code{grep -r linux *}, il loop
+nella directory porterebbe il comando ad esaminare \file{/boot},
+\file{/boot/boot}, \file{/boot/boot/boot} e così via.
Per questo motivo il kernel e le librerie prevedono che nella risoluzione di
-un \textit{pathname} possano essere seguiti un numero limitato di link
+un \textit{pathname} possano essere seguiti un numero limitato di collegamenti
simbolici, il cui valore limite è specificato dalla costante
\const{MAXSYMLINKS}. Qualora questo limite venga superato viene generato un
-errore ed \var{errno} viene impostata al valore \errcode{ELOOP}.
+errore ed \var{errno} viene impostata al valore \errcode{ELOOP}, che nella
+quasi totalità dei casi indica appunto che si è creato un collegamento
+simbolico che fa riferimento ad una directory del suo stesso
+\textit{pathname}.
+
+Un altro punto da tenere sempre presente è che, come abbiamo accennato, un
+collegamento simbolico può fare riferimento anche ad un file che non esiste;
+ad esempio possiamo usare il comando \cmd{ln} per creare un collegamento
+simbolico nella nostra directory con:
+\begin{Command}
+$ ln -s /tmp/tmp_file symlink
+\end{Command}
+%$
+e questo avrà successo anche se \file{/tmp/tmp\_file} non esiste:
+\begin{Command}
+$ ls symlink
+\end{Command}
+\begin{Terminal}
+symlink
+\end{Terminal}
+%$
+ma questo può generare confusione, perché accedendo in sola lettura a
+\file{symlink}, ad esempio con \cmd{cat}, otterremmo un errore:
+\begin{Command}
+$ cat symlink
+\end{Command}
+\begin{Terminal}
+cat: symlink: No such file or directory
+\end{Terminal}
+%$
+con un errore che può sembrare sbagliato, dato che \cmd{ls} ci ha mostrato
+l'esistenza di \file{symlink}, mentre se invece scrivessimo su \file{symlink}
+otterremmo semplicemente la creazione di \file{/tmp/tmp\_file}.
+
+
+\itindend{symbolic~link}
+\index{collegamento!simbolico|)}
+
+
+
+Un'altra funzione relativa alla gestione dei nomi dei file, anche se a prima
+vista parrebbe fare riferimento ad un argomento completamente diverso, è
+quella che consente la cancellazione di un file. Il punto è che in realtà una
+funzione che serva proprio a cancellare un file non esiste neanche, perché
+come accennato in sez.~\ref{sec:file_filesystem}, quando in un sistema
+unix-like si richiede la rimozione di un file quello che si va a cancellare è
+soltanto la voce che referenzia il suo \textit{inode} all'interno di una
+directory.
-Un punto da tenere sempre presente è che, come abbiamo accennato, un link
-simbolico può fare riferimento anche ad un file che non esiste; ad esempio
-possiamo creare un file temporaneo nella nostra directory con un link del
-tipo:
-\begin{verbatim}
-$ ln -s /tmp/tmp_file temporaneo
-\end{verbatim}%$
-anche se \file{/tmp/tmp\_file} non esiste. Questo può generare confusione, in
-quanto aprendo in scrittura \file{temporaneo} verrà creato
-\file{/tmp/tmp\_file} e scritto; ma accedendo in sola lettura a
-\file{temporaneo}, ad esempio con \cmd{cat}, otterremmo:
-\begin{verbatim}
-$ cat temporaneo
-cat: temporaneo: No such file or directory
-\end{verbatim}%$
-con un errore che può sembrare sbagliato, dato che un'ispezione con \cmd{ls}
-ci mostrerebbe invece l'esistenza di \file{temporaneo}.
+La funzione di sistema che consente di effettuare questa operazione, il cui
+nome come si può notare ha poco a che fare con il concetto di rimozione, è
+\funcd{unlink}, ed il suo prototipo è:
+
+\begin{funcproto}{
+\fhead{unistd.h}
+\fdecl{int unlink(const char *pathname)}
+\fdesc{Cancella un file.}
+}
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore,
+ nel qual caso \var{errno} assumerà uno dei valori:
+ \begin{errlist}
+ \item[\errcode{EISDIR}] \param{pathname} si riferisce ad una
+ directory.\footnotemark
+ \item[\errcode{EROFS}] \param{pathname} è su un filesystem montato in sola
+ lettura.
+ \item[\errcode{EISDIR}] \param{pathname} fa riferimento a una directory.
+ \end{errlist} ed inoltre \errval{EACCES}, \errval{EFAULT}, \errval{ENOENT},
+ \errval{ENOTDIR}, \errval{ENOMEM}, \errval{EROFS}, \errval{ELOOP},
+ \errval{EIO} nel loro significato generico.}
+\end{funcproto}
+
+\footnotetext{questo è un valore specifico ritornato da Linux che non consente
+ l'uso di \func{unlink} con le directory. Non è conforme allo standard
+ POSIX, che prescrive invece l'uso di \errcode{EPERM} in caso l'operazione
+ non sia consentita o il processo non abbia privilegi sufficienti.}
+
+La funzione elimina il nome specificato dall'argomento \param{pathname} nella
+directory che lo contiene e decrementa il numero di riferimenti nel relativo
+\itindex{inode} \textit{inode}. Nel caso di socket, fifo o file di dispositivo
+\index{file!di~dispositivo} rimuove il nome, ma come per i file normali i
+processi che hanno aperto uno di questi oggetti possono continuare ad
+utilizzarli. Solo nel caso di cancellazione di un collegamento simbolico, che
+consiste solo nel rimando ad un altro file, questo viene immediatamente
+eliminato.
+
+Per cancellare una voce in una directory è necessario avere il permesso di
+scrittura su di essa, dato che si va a rimuovere una voce dal suo contenuto, e
+il diritto di esecuzione sulla directory che la contiene (affronteremo in
+dettaglio l'argomento dei permessi di file e directory in
+sez.~\ref{sec:file_access_control}). Se inoltre lo \itindex{sticky~bit}
+\textit{sticky bit} (vedi sez.~\ref{sec:file_special_perm}) è impostato
+occorrerà anche essere proprietari del file o proprietari della directory o
+avere i privilegi di amministratore.
+
+Una delle caratteristiche comuni fra \func{link} ed \func{unlink} è che la
+creazione/rimozione del nome dalla directory e l'incremento/decremento del
+numero di riferimenti \itindex{inode} nell'\textit{inode} sono sempre
+effettuati in maniera atomica (si veda sez.~\ref{sec:proc_atom_oper}) senza
+possibili interruzioni fra le due operazioni, questo entrambe queste funzioni
+sono realizzate tramite una \textit{system call}.
+
+Si ricordi inoltre che anche se ne è rimosso il nome da una directory un file
+non viene eliminato dal disco fintanto che tutti i riferimenti ad esso sono
+stati cancellati: solo quando il numero di collegamenti mantenuto
+\itindex{inode} nell'\textit{inode} diventa nullo, questo viene disallocato lo
+spazio occupato su disco viene liberato. Si tenga presente comunque che a
+questo si aggiunge sempre un'ulteriore condizione e cioè che non ci siano
+processi che abbiano il suddetto file aperto.\footnote{come vedremo in
+ cap.~\ref{cha:file_unix_interface} il kernel mantiene anche una tabella dei
+ file aperti nei vari processi, che a sua volta contiene i riferimenti agli
+ \itindex{inode} \textit{inode} ad essi relativi; prima di procedere alla
+ cancellazione dello spazio occupato su disco dal contenuto di un file il
+ kernel controlla anche questa tabella, per verificare che anche in essa non
+ ci sia più nessun riferimento all'\textit{inode} in questione.}
+
+Questa caratteristica del sistema viene spesso usata per essere sicuri di non
+lasciare file temporanei su disco in caso di crash dei programmi. La tecnica è
+quella di creare un nuovo file e chiamare \func{unlink} subito dopo, in questo
+modo il contenuto del file sarà sempre disponibile all'interno del processo
+attraverso il suo file descriptor (vedi sez.~\ref{sec:file_fd}) fintanto che
+il processo non chiude il file, ma non ne resta traccia in nessuna directory,
+e lo spazio occupato su disco viene immediatamente rilasciato alla conclusione
+del processo (quando tutti i file vengono chiusi).
+
+Al contrario di quanto avviene con altri Unix, in Linux non è possibile usare
+la funzione \func{unlink} sulle directory, per le quali si otterrebbe un
+errore di \errcode{EISDIR}. Per cancellare una directory si può usare la
+apposita funzione di sistema \func{rmdir} (che vedremo in
+sez.~\ref{sec:file_dir_creat_rem}), oppure la funzione \func{remove}.
+Quest'ultima è la funzione prevista dallo standard ANSI C per effeettuare una
+cancellazione generica di un file o di una directory e funziona anche per i
+sistemi operativo che non supportano gli \textit{hard link}. Nei sistemi
+unix-like \funcd{remove} è equivalente ad usare in maniera trasparente
+\func{unlink} per i file ed \func{rmdir} per le directory; il suo prototipo è:
+
+\begin{funcproto}{
+\fhead{stdio.h}
+\fdecl{int remove(const char *pathname)}
+\fdesc{Cancella un file o una directory.}
+}
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
+ caso \var{errno} assumerà uno dei valori relativi alla chiamata utilizzata,
+ pertanto si può fare riferimento a quanto illustrato nelle descrizioni di
+ \func{unlink} e \func{rmdir}.}
+\end{funcproto}
+
+La funzione utilizza la funzione \func{unlink} per cancellare i file e la
+funzione \func{rmdir} (vedi sez.~\ref{sec:file_dir_creat_rem}) per cancellare
+le directory.\footnote{questo vale usando la \acr{glibc}; nella libc4 e nella
+ libc5 la funzione \func{remove} era un semplice alias alla funzione
+ \func{unlink} e quindi non poteva essere usata per le directory.} Si tenga
+presente che per alcune implementazioni del protocollo NFS utilizzare questa
+funzione può comportare la scomparsa di file ancora in uso.
+
+Infine per cambiare nome ad un file o a una directory si usa la funzione di
+sistema \funcd{rename},\footnote{la funzione è definita dallo standard ANSI C,
+ ma si applica solo per i file, lo standard POSIX estende la funzione anche
+ alle directory.} il cui prototipo è:
+
+\begin{funcproto}{
+\fhead{stdio.h}
+\fdecl{int rename(const char *oldpath, const char *newpath)}
+\fdesc{Rinomina un file o una directory.}
+}
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore,
+ nel qual caso \var{errno} assumerà uno dei valori:
+ \begin{errlist}
+ \item[\errcode{EACCESS}] non c'è permesso di scrivere nelle directory
+ contenenti \param{oldpath} e \param{newpath} o di attraversare
+ quelle dei loro \textit{pathname} o di scrivere su \param{newpath}
+ se questa è una directory.
+ \item[\errcode{EBUSY}] o \param{oldpath} o \param{newpath} sono in uso da
+ parte di qualche processo (come \index{directory~di~lavoro} directory di
+ lavoro o come radice) o del sistema (come \itindex{mount~point}
+ \textit{mount point}) ed il sistema non riesce a risolvere la situazione.
+ \item[\errcode{EINVAL}] \param{newpath} contiene un prefisso di
+ \param{oldpath} o più in generale si è cercato di creare una directory come
+ sotto-directory di sé stessa.
+ \item[\errcode{EISDIR}] \param{newpath} è una directory mentre
+ \param{oldpath} non è una directory.
+ \item[\errcode{EEXIST}] \param{newpath} è una directory già esistente e
+ non è vuota (anche \errcode{ENOTEMPTY}).
+ \item[\errcode{ENOTDIR}] uno dei componenti dei \textit{pathname} non è una
+ directory o \param{oldpath} è una directory e
+ \param{newpath} esiste e non è una directory.
+ \item[\errval{EPERM}] la directory contenente \param{oldpath} o quella
+ contenente un \param{newpath} esistente hanno lo
+ \itindex{sticky~bit} \textit{sticky bit} e non si è i proprietari dei
+ rispettivi file (o non si hanno privilegi amministrativi) oppure il
+ filesystem non supporta l'operazione.
+ \item[\errcode{EXDEV}] \param{oldpath} e \param{newpath} non sono sullo
+ stesso filesystem e sotto lo stesso \itindex{mount~point} \textit{mount
+ point}.
+ \end{errlist} ed inoltre \errval{EFAULT}, \errval{ELOOP}, \errval{EMLINK},
+ \errval{ENAMETOOLONG}, \errval{ENOENT}, \errval{ENOMEM}, \errval{ENOSPC} e
+ \errval{EROFS} nel loro significato generico.}
+\end{funcproto}
+
+La funzione rinomina in \param{newpath} il file o la directory indicati
+dall'argomento \param{oldpath}. Il nome viene eliminato nella directory
+originale e ricreato nella directory di destinazione mantenendo il riferimento
+allo stesso \itindex{inode} \textit{inode}. Non viene spostato nessun dato e
+\itindex{inode} l'\textit{inode} del file non subisce nessuna modifica in
+quanto le modifiche sono eseguite sulle directory che
+contengono \param{newpath} ed \param{oldpath}.
+
+Il vantaggio nell'uso di questa funzione al posto della chiamata successiva di
+\func{link} e \func{unlink} è che l'operazione è eseguita atomicamente, non
+c'è modifica, per quanto temporanea, al \textit{link count} del file e non può
+esistere cioè nessun istante in cui un altro processo possa trovare attivi
+entrambi i nomi dello stesso file (a parte il caso di sovrascrittura), o, in
+caso di sostituzione di un file esistente, non trovare quest'ultimo prima che
+la sostituzione sia stata eseguita.
+
+Dato che opera in maniera analoga la funzione è soggetta alle stesse
+restrizioni di \func{link}, quindi è necessario che \param{oldpath}
+e \param{newpath} siano nello stesso filesystem e facciano riferimento allo
+stesso \itindex{mount~point} \textit{mount point}, e che il filesystem
+supporti questo tipo di operazione. Qualora questo non avvenga si dovrà
+effettuare l'operazione in maniera non atomica copiando il file a destinazione
+e poi cancellando l'orginale.
+
+Il comportamento della funzione è diverso a seconda che si voglia rinominare
+un file o una directory. Se ci riferisce ad un file allora \param{newpath}, se
+esiste, non deve essere una directory, altrimenti si avrà un errore di
+\errcode{EISDIR}. Se \param{newpath} indica un file già esistente questo verrà
+rimpiazzato atomicamente, ma nel caso in cui \func{rename} fallisca esso non
+sarà toccato. I caso di sovrascrittura esisterà però una breve finestra di
+tempo in cui sia \param{oldpath} che \param{newpath} potranno fare entrambi
+riferimento al file che viene rinominato.
+
+Se \param{oldpath} è una directory allora \param{newpath}, se esistente, deve
+essere una directory vuota, altrimenti si avranno gli errori \errcode{ENOTDIR}
+(se non è una directory) o \errcode{ENOTEMPTY} o \errcode{EEXIST} (se non è
+vuota). Chiaramente \param{newpath} non potrà contenere \param{oldpath} nel
+suo \textit{pathname}, non essendo possibile rendere una directory
+sottodirectory di sé stessa, nel qual caso si avrà un errore di
+\errcode{EINVAL}.
+
+Se \param{oldpath} si riferisce ad un collegamento simbolico questo sarà
+rinominato restando tale senza nessun effetto sul file a cui fa riferimento.
+Se invece \param{newpath} esiste ed è un collegamento simbolico verrà
+cancellato come qualunque altro file. Infine qualora \param{oldpath}
+e \param{newpath} siano due nomi che già fanno riferimento allo stesso file lo
+standard POSIX prevede che la funzione non ritorni un errore, e semplicemente
+non faccia nulla, lasciando entrambi i nomi. Linux segue questo standard,
+anche se, come fatto notare dal manuale della \acr{glibc}, il comportamento
+più ragionevole sarebbe quello di cancellare \param{oldpath}.
+
+In tutti i casi si dovranno avere i permessi di scrittura nelle directory
+contenenti \param{oldpath} e \param{newpath}, e nel caso \param{newpath} sia
+una directory vuota già esistente anche su di essa (perché dovrà essere
+aggiornata la voce ``\texttt{..}''). Se poi le directory
+contenenti \param{oldpath} o \param{newpath} hanno lo \itindex{sticky~bit}
+\textit{sticky bit} attivo (vedi sez.~\ref{sec:file_special_perm}) si dovrà
+essere i proprietari dei file (o delle directory) che si vogliono rinominare,
+o avere i permessi di amministratore.
\subsection{La creazione e la cancellazione delle directory}
\label{sec:file_dir_creat_rem}
Benché in sostanza le directory non siano altro che dei file contenenti
-elenchi di nomi ed \itindex{inode} \textit{inode}, non è possibile trattarle
-come file ordinari e devono essere create direttamente dal kernel attraverso
-una opportuna system call.\footnote{questo è quello che permette anche,
- attraverso l'uso del VFS, l'utilizzo di diversi formati per la gestione dei
- suddetti elenchi, dalle semplici liste a strutture complesse come alberi
- binari, hash, ecc. che consentono una ricerca veloce quando il numero di
- file è molto grande.} La funzione usata per creare una directory è
+elenchi di nomi con riferimenti ai rispettivi \itindex{inode} \textit{inode},
+non è possibile trattarle come file ordinari e devono essere create
+direttamente dal kernel attraverso una opportuna \textit{system
+ call}.\footnote{questo è quello che permette anche, attraverso l'uso del
+ VFS, l'utilizzo di diversi formati per la gestione dei suddetti elenchi,
+ dalle semplici liste a strutture complesse come alberi binari, hash,
+ ecc. che consentono una ricerca veloce quando il numero di file è molto
+ grande.} La funzione di sistema usata per creare una directory è
\funcd{mkdir}, ed il suo prototipo è:
-\begin{functions}
- \headdecl{sys/stat.h}
- \headdecl{sys/types.h}
- \funcdecl{int mkdir(const char *dirname, mode\_t mode)}
- Crea una nuova directory.
-
- \bodydesc{La funzione restituisce zero in caso di successo e -1 per un
- errore, nel qual caso \var{errno} assumerà i valori:
+\begin{funcproto}{
+\fhead{sys/stat.h}
+\fhead{sys/types.h}
+\fdecl{int mkdir(const char *dirname, mode\_t mode)}
+\fdesc{Crea una nuova directory.}
+}
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
+ caso \var{errno} assumerà uno dei valori:
\begin{errlist}
\item[\errcode{EEXIST}] un file (o una directory) con quel nome esiste di
già.
\item[\errcode{ENOSPC}] non c'è abbastanza spazio sul file system per creare
la nuova directory o si è esaurita la quota disco dell'utente.
\end{errlist}
- ed inoltre anche \errval{EPERM}, \errval{EFAULT}, \errval{ENAMETOOLONG},
- \errval{ENOENT}, \errval{ENOTDIR}, \errval{ENOMEM}, \errval{ELOOP},
- \errval{EROFS}.}
-\end{functions}
-
-La funzione crea una nuova directory vuota, che contiene cioè solo le due voci
-standard presenti in ogni directory (cioè ``\file{.}'' e ``\file{..}''), con
-il nome indicato dall'argomento \param{dirname}. Il nome può essere indicato
-sia come \itindsub{pathname}{assoluto} \textit{pathname} assoluto che come
-\itindsub{pathname}{relativo} \textit{pathname} relativo.
-
-I permessi di accesso (vedi sez.~\ref{sec:file_access_control}) con cui la
-directory viene creata sono specificati dall'argomento \param{mode}, i cui
-possibili valori sono riportati in tab.~\ref{tab:file_permission_const}; si
-tenga presente che questi sono modificati dalla maschera di creazione dei file
-(si veda sez.~\ref{sec:file_perm_management}). La titolarità della nuova
-directory è impostata secondo quanto riportato in
-sez.~\ref{sec:file_ownership_management}.
-
-La funzione che permette la cancellazione di una directory è invece
-\funcd{rmdir}, ed il suo prototipo è:
-\begin{prototype}{sys/stat.h}{int rmdir(const char *dirname)}
- Cancella una directory.
-
- \bodydesc{La funzione restituisce zero in caso di successo e -1 per un
- errore, nel qual caso \var{errno} assumerà i valori:
- \begin{errlist}
- \item[\errcode{EPERM}] il filesystem non supporta la cancellazione di
- directory, oppure la directory che contiene \param{dirname} ha lo
- \itindex{sticky~bit} \textit{sticky bit} impostato e l'\ids{UID} effettivo
- del processo non corrisponde al proprietario della directory.
- \item[\errcode{EACCES}] non c'è il permesso di scrittura per la directory
- che contiene la directory che si vuole cancellare, o non c'è il permesso
- di attraversare (esecuzione) una delle directory specificate in
- \param{dirname}.
- \item[\errcode{EBUSY}] la directory specificata è la
- \index{directory~di~lavoro} directory di lavoro o la radice di qualche
- processo.
- \item[\errcode{ENOTEMPTY}] la directory non è vuota.
- \end{errlist}
- ed inoltre anche \errval{EFAULT}, \errval{ENAMETOOLONG}, \errval{ENOENT},
- \errval{ENOTDIR}, \errval{ENOMEM}, \errval{ELOOP}, \errval{EROFS}.}
-\end{prototype}
-
-La funzione cancella la directory \param{dirname}, che deve essere vuota (la
-directory deve cioè contenere soltanto le due voci standard ``\file{.}'' e
-``\file{..}''). Il nome può essere indicato con il \textit{pathname} assoluto
-o relativo.
-
-La modalità con cui avviene la cancellazione è analoga a quella di
-\func{unlink}: fintanto che il numero di link \itindex{inode}
-all'\textit{inode} della directory non diventa nullo e nessun processo ha la
-directory aperta lo spazio occupato su disco non viene rilasciato. Se un
-processo ha la directory aperta la funzione rimuove il link \itindex{inode}
-all'\textit{inode} e nel caso sia l'ultimo, pure le voci standard ``\file{.}''
-e ``\file{..}'', a questo punto il kernel non consentirà di creare più nuovi
-file nella directory.
-
-
-\subsection{La creazione di file speciali}
-\label{sec:file_mknod}
-
-\index{file!di~dispositivo|(}
-
-Finora abbiamo parlato esclusivamente di file, directory e link simbolici; in
-sez.~\ref{sec:file_file_types} abbiamo visto però che il sistema prevede pure
-degli altri tipi di file speciali, come i file di dispositivo, le fifo ed i
-socket (questi ultimi sono un caso a parte, essendo associati anche alla
-comunicazione via rete, per cui ci saranno trattati in dettaglio a partire da
-cap.~\ref{cha:socket_intro}).
-
-La manipolazione delle caratteristiche di questi diversi tipi di file e la
-loro cancellazione può essere effettuata con le stesse funzioni che operano
-sui file regolari; ma quando li si devono creare sono necessarie delle
-funzioni apposite. La prima di queste funzioni è \funcd{mknod}, il cui
-prototipo è:
-\begin{functions}
- \headdecl{sys/types.h}
- \headdecl{sys/stat.h}
- \headdecl{fcntl.h}
- \headdecl{unistd.h}
- \funcdecl{int mknod(const char *pathname, mode\_t mode, dev\_t dev)}
-
- Crea un \textit{inode} del tipo specificato sul filesystem.
-
- \bodydesc{La funzione restituisce zero in caso di successo e -1 per un
- errore, nel qual caso \var{errno} assumerà i valori:
- \begin{errlist}
- \item[\errcode{EPERM}] non si hanno privilegi sufficienti a creare
- l'\texttt{inode}, o il filesystem su cui si è cercato di
- creare \param{pathname} non supporta l'operazione.
- \item[\errcode{EINVAL}] il valore di \param{mode} non indica un file, una
- fifo, un socket o un dispositivo.
- \item[\errcode{EEXIST}] \param{pathname} esiste già o è un link simbolico.
- \end{errlist}
- ed inoltre anche \errval{EFAULT}, \errval{EACCES}, \errval{ENAMETOOLONG},
- \errval{ENOENT}, \errval{ENOTDIR}, \errval{ENOMEM}, \errval{ELOOP},
- \errval{ENOSPC}, \errval{EROFS}.}
-\end{functions}
-
-La funzione, come suggerisce il nome, permette di creare un ``\textsl{nodo}''
-sul filesystem, e viene in genere utilizzata per creare i file di dispositivo,
-ma si può usare anche per creare file regolari. L'argomento
-\param{mode} specifica sia il tipo di file che si vuole creare che i relativi
-permessi, secondo i valori riportati in tab.~\ref{tab:file_mode_flags}, che
-vanno combinati con un OR binario. I permessi sono comunque modificati nella
-maniera usuale dal valore di \itindex{umask} \textit{umask} (si veda
-sez.~\ref{sec:file_perm_management}).
-
-Per il tipo di file può essere specificato solo uno fra i seguenti valori:
-\const{S\_IFREG} per un file regolare (che sarà creato vuoto),
-\const{S\_IFBLK} per un dispositivo a blocchi, \const{S\_IFCHR} per un
-dispositivo a caratteri, \const{S\_IFSOCK} per un socket e \const{S\_IFIFO}
-per una fifo;\footnote{con Linux la funzione non può essere usata per creare
- directory o link simbolici, si dovranno usare le funzioni \func{mkdir} e
- \func{symlink} a questo dedicate.} un valore diverso comporterà l'errore
-\errcode{EINVAL}.
-
-Qualora si sia specificato in \param{mode} un file di dispositivo (vale a dire
-o \const{S\_IFBLK} o \const{S\_IFCHR}), il valore di \param{dev} dovrà essere
-usato per indicare a quale dispositivo si fa riferimento, altrimenti il suo
-valore verrà ignorato. Solo l'amministratore può creare un file di
-dispositivo usando questa funzione (il processo deve avere la
-\itindex{capabilities} \textit{capability} \const{CAP\_MKNOD}), ma in
-Linux\footnote{questo è un comportamento specifico di Linux, la funzione non è
- prevista dallo standard POSIX.1 originale, mentre è presente in SVr4 e
- 4.4BSD, ma esistono differenze nei comportamenti e nei codici di errore,
- tanto che questa è stata introdotta in POSIX.1-2001 con una nota che la
- definisce portabile solo quando viene usata per creare delle fifo, ma
- comunque deprecata essendo utilizzabile a tale scopo la specifica
- \func{mkfifo}.} l'uso per la creazione di un file ordinario, di una fifo o
-di un socket è consentito anche agli utenti normali.
-
-I nuovi \itindex{inode} \textit{inode} creati con \func{mknod} apparterranno
-al proprietario e al gruppo del processo che li ha creati, a meno che non si
-sia attivato il bit \acr{sgid} per la directory o sia stata attivata la
-semantica BSD per il filesystem (si veda
-sez.~\ref{sec:file_ownership_management}) in cui si va a creare
-\itindex{inode} l'\textit{inode}.
-
-Nella creazione di un file di dispositivo occorre poi specificare
-correttamente il valore di \param{dev}; questo infatti è di tipo
-\type{dev\_t}, che è un tipo primitivo (vedi
-tab.~\ref{tab:intro_primitive_types}) riservato per indicare un
-\textsl{numero} di dispositivo; il kernel infatti identifica ciascun
-dispositivo con un valore numerico. Originariamente questo era un intero a 16
-bit diviso in due parti di 8 bit chiamate rispettivamente
-\itindex{major~number} \textit{major number} e \itindex{minor~number}
-\textit{minor number}, che sono poi i due numeri mostrati dal comando
-\texttt{ls -l} al posto della dimensione quando lo si esegue su un file di
-dispositivo.
-
-Il \itindex{major~number} \textit{major number} identifica una classe di
-dispositivi (ad esempio la seriale, o i dischi IDE) e serve in sostanza per
-indicare al kernel quale è il modulo che gestisce quella classe di
-dispositivi; per identificare uno specifico dispositivo di quella classe (ad
-esempio una singola porta seriale, o una partizione di un disco) si usa invece
-il \itindex{minor~number} \textit{minor number}. L'elenco aggiornato di questi
-numeri con le relative corrispondenze ai vari dispositivi può essere trovato
-nel file \texttt{Documentation/devices.txt} allegato alla documentazione dei
-sorgenti del kernel.
-
-Data la crescita nel numero di dispositivi supportati, ben presto il limite
-massimo di 256 si è rivelato troppo basso, e nel passaggio dai kernel della
-serie 2.4 alla serie 2.6 è stata aumentata a 32 bit la dimensione del tipo
-\type{dev\_t}, con delle dimensioni passate a 12 bit per il
-\itindex{major~number} \textit{major number} e 20 bit per il
-\itindex{minor~number} \textit{minor number}. La transizione però ha anche
-comportato il passaggio di \type{dev\_t} a \index{tipo!opaco} tipo opaco, e la
-necessità di specificare il numero tramite delle opportune macro, così da non
-avere problemi di compatibilità con eventuali ulteriori estensioni.
+ ed inoltre \errval{EPERM}, \errval{EFAULT}, \errval{ENAMETOOLONG},
+ \errval{ENOENT}, \errval{ENOTDIR}, \errval{ENOMEM}, \errval{ELOOP},
+ \errval{EROFS} nel loro significato generico.}
+\end{funcproto}
-Le macro sono definite nel file \headfile{sys/sysmacros.h}, che viene
-automaticamente incluso quando si include \headfile{sys/types.h}; si possono
-pertanto ottenere i valori del \itindex{major~number} \textit{major number} e
-\itindex{minor~number} \textit{minor number} di un dispositivo rispettivamente
-con le macro \macro{major} e \macro{minor}:
-\begin{functions}
- \headdecl{sys/types.h}
- \funcdecl{int \macro{major}(dev\_t dev)}
- Restituisce il \itindex{major~number} \textit{major number} del dispositivo
- \param{dev}.
-
- \funcdecl{int \macro{minor}(dev\_t dev)}
- Restituisce il \itindex{minor~number} \textit{minor number} del dispositivo
- \param{dev}.
-\end{functions}
-\noindent mentre una volta che siano noti \itindex{major~number} \textit{major
- number} e \itindex{minor~number} \textit{minor number} si potrà costruire il
-relativo identificativo con la macro \macro{makedev}:
-\begin{functions}
- \headdecl{sys/types.h}
- \funcdecl{dev\_t \macro{minor}(int major, int minor)}
- Restituisce l'identificativo di un dispositivo dati \itindex{major~number}
- \textit{major number} e \itindex{minor~number} \textit{minor number}.
-\end{functions}
-\index{file!di~dispositivo|)}
+La funzione crea una nuova directory vuota, che contiene cioè solo le due voci
+standard presenti in ogni directory (cioè ``\file{.}'' e ``\file{..}''), con
+il nome indicato dall'argomento \param{dirname}. Il nome può essere indicato
+sia come \itindsub{pathname}{assoluto} \textit{pathname} assoluto che come
+\itindsub{pathname}{relativo} \textit{pathname} relativo.
+
+I permessi di accesso (vedi sez.~\ref{sec:file_access_control}) con cui la
+directory viene creata sono specificati dall'argomento \param{mode}, i cui
+possibili valori sono riportati in tab.~\ref{tab:file_permission_const}; si
+tenga presente che questi sono modificati dalla maschera di creazione dei file
+(si veda sez.~\ref{sec:file_perm_management}). La titolarità della nuova
+directory è impostata secondo quanto riportato in
+sez.~\ref{sec:file_ownership_management}.
+
+La funzione che permette la cancellazione di una directory è invece
+\funcd{rmdir}, ed il suo prototipo è:
+\begin{prototype}{sys/stat.h}{int rmdir(const char *dirname)}
+ Cancella una directory.
-Infine con lo standard POSIX.1-2001 è stata introdotta una funzione specifica
-per creare una fifo (tratteremo le fifo in in sez.~\ref{sec:ipc_named_pipe});
-la funzione è \funcd{mkfifo} ed il suo prototipo è:
-\begin{functions}
- \headdecl{sys/types.h} \headdecl{sys/stat.h}
-
- \funcdecl{int mkfifo(const char *pathname, mode\_t mode)}
-
- Crea una fifo.
-
\bodydesc{La funzione restituisce zero in caso di successo e -1 per un
- errore, nel qual caso \var{errno} assumerà i valori \errval{EACCES},
- \errval{EEXIST}, \errval{ENAMETOOLONG}, \errval{ENOENT}, \errval{ENOSPC},
- \errval{ENOTDIR} e \errval{EROFS}.}
-\end{functions}
+ errore, nel qual caso \var{errno} assumerà i valori:
+ \begin{errlist}
+ \item[\errcode{EPERM}] il filesystem non supporta la cancellazione di
+ directory, oppure la directory che contiene \param{dirname} ha lo
+ \itindex{sticky~bit} \textit{sticky bit} impostato e l'\ids{UID} effettivo
+ del processo non corrisponde al proprietario della directory.
+ \item[\errcode{EACCES}] non c'è il permesso di scrittura per la directory
+ che contiene la directory che si vuole cancellare, o non c'è il permesso
+ di attraversare (esecuzione) una delle directory specificate in
+ \param{dirname}.
+ \item[\errcode{EBUSY}] la directory specificata è la
+ \index{directory~di~lavoro} directory di lavoro o la radice di qualche
+ processo.
+ \item[\errcode{ENOTEMPTY}] la directory non è vuota.
+ \end{errlist}
+ ed inoltre anche \errval{EFAULT}, \errval{ENAMETOOLONG}, \errval{ENOENT},
+ \errval{ENOTDIR}, \errval{ENOMEM}, \errval{ELOOP}, \errval{EROFS}.}
+\end{prototype}
-La funzione crea la fifo \param{pathname} con i permessi \param{mode}. Come
-per \func{mknod} il file \param{pathname} non deve esistere (neanche come link
-simbolico); al solito i permessi specificati da \param{mode} vengono
-modificati dal valore di \itindex{umask} \textit{umask}.
+La funzione cancella la directory \param{dirname}, che deve essere vuota (la
+directory deve cioè contenere soltanto le due voci standard ``\file{.}'' e
+``\file{..}''). Il nome può essere indicato con il \textit{pathname} assoluto
+o relativo.
+
+La modalità con cui avviene la cancellazione è analoga a quella di
+\func{unlink}: fintanto che il numero di collegamenti \itindex{inode}
+all'\textit{inode} della directory non diventa nullo e nessun processo ha la
+directory aperta lo spazio occupato su disco non viene rilasciato. Se un
+processo ha la directory aperta la funzione rimuove il collegamento
+\itindex{inode} all'\textit{inode} e nel caso sia l'ultimo, pure le voci
+standard ``\file{.}'' e ``\file{..}'', a questo punto il kernel non
+consentirà di creare più nuovi file nella directory.
ad un \textit{directory stream} si può usare la funzione
\funcd{dirfd},\footnote{questa funzione è una estensione introdotta con BSD
4.3-Reno ed è presente in Linux con le libc5 (a partire dalla versione
- 5.1.2) e con le \acr{glibc} ma non presente in POSIX fino alla revisione
+ 5.1.2) e con la \acr{glibc} ma non presente in POSIX fino alla revisione
POSIX.1-2008, per questo per poterla utilizzare fino alla versione 2.10
- delle \acr{glibc} era necessario definire le macro \macro{\_BSD\_SOURCE} o
+ della \acr{glibc} era necessario definire le macro \macro{\_BSD\_SOURCE} o
\macro{\_SVID\_SOURCE}, dalla versione 2.10 si possono usare anche
\texttt{\macro{\_POSIX\_C\_SOURCE} >= 200809L} o
\texttt{\macro{\_XOPEN\_SOURCE} >= 700}.} il cui prototipo è:
Viceversa se si è aperto un file descriptor corrispondente ad una directory è
possibile associarvi un \textit{directory stream} con la funzione
\funcd{fdopendir},\footnote{questa funzione è però disponibile solo a partire
- dalla versione 2.4 delle \acr{glibc}, ed è stata introdotta nello standard
+ dalla versione 2.4 della \acr{glibc}, ed è stata introdotta nello standard
POSIX solo a partire dalla revisione POSIX.1-2008, prima della versione 2.10
- delle \acr{glibc} per poterla utilizzare era necessario definire la macro
+ della \acr{glibc} per poterla utilizzare era necessario definire la macro
\macro{\_GNU\_SOURCE}, dalla versione 2.10 si possono usare anche
\texttt{\macro{\_POSIX\_C\_SOURCE} >= 200809L} o \texttt{\_XOPEN\_SOURCE >=
700} .} il cui prototipo è:
\const{DT\_UNKNOWN} & Tipo sconosciuto.\\
\const{DT\_REG} & File normale.\\
\const{DT\_DIR} & Directory.\\
- \const{DT\_LNK} & Link simbolico.\\
+ \const{DT\_LNK} & Collegamento simbolico.\\
\const{DT\_FIFO} & Fifo.\\
\const{DT\_SOCK} & Socket.\\
\const{DT\_CHR} & Dispositivo a caratteri.\\
\end{table}
Per quanto riguarda il significato dei campi opzionali, il campo \var{d\_type}
-indica il tipo di file (se fifo, directory, link simbolico, ecc.), e consente
+indica il tipo di file (se fifo, directory, collegamento simbolico, ecc.), e consente
di evitare una successiva chiamata a \func{lstat} per determinarlo. I suoi
possibili valori sono riportati in tab.~\ref{tab:file_dtype_macro}. Si tenga
presente che questo valore è disponibile solo per i filesystem che ne
supportano la restituzione (fra questi i più noti sono \textsl{btrfs},
\textsl{ext2}, \textsl{ext3}, e \textsl{ext4}), per gli altri si otterrà
sempre il valore \const{DT\_UNKNOWN}.\footnote{inoltre fino alla versione 2.1
- delle \acr{glibc}, pur essendo il campo \var{d\_type} presente, il suo uso
+ della \acr{glibc}, pur essendo il campo \var{d\_type} presente, il suo uso
non era implementato, e veniva restituito comunque il valore
\const{DT\_UNKNOWN}.}
esso pertanto deve essere stato ottenuto o dal valore di \var{d\_off} di
\struct{dirent} o dal valore restituito dalla funzione \funcd{telldir}, che
legge la posizione corrente; il prototipo di quest'ultima è:\footnote{prima
- delle \acr{glibc} 2.1.1 la funzione restituiva un valore di tipo
+ della \acr{glibc} 2.1.1 la funzione restituiva un valore di tipo
\type{off\_t}, sostituito a partire dalla versione 2.1.2 da \ctyp{long} per
conformità a POSIX.1-2001.}
\begin{prototype}{dirent.h}{long telldir(DIR *dir)}
La funzione \func{alphasort} deriva da BSD ed è presente in Linux fin dalle
\acr{libc4}\footnote{la versione delle \acr{libc4} e \acr{libc5} usa però come
- argomenti dei puntatori a delle strutture \struct{dirent}; le glibc usano il
+ argomenti dei puntatori a delle strutture \struct{dirent}; la glibc usa il
prototipo originario di BSD, mostrato anche nella definizione, che prevede
puntatori a \ctyp{void}.} e deve essere specificata come argomento
\param{compar} per ottenere un ordinamento alfabetico (secondo il valore del
-campo \var{d\_name} delle varie voci). Le \acr{glibc} prevedono come
-estensione\footnote{le glibc, a partire dalla versione 2.1, effettuano anche
- l'ordinamento alfabetico tenendo conto delle varie localizzazioni, usando
- \funcm{strcoll} al posto di \funcm{strcmp}.} anche \func{versionsort}, che
-ordina i nomi tenendo conto del numero di versione (cioè qualcosa per cui
-\texttt{file10} viene comunque dopo \texttt{file4}.)
+campo \var{d\_name} delle varie voci). La \acr{glibc} prevede come
+estensione\footnote{la \acr{glibc}, a partire dalla versione 2.1, effettua
+ anche l'ordinamento alfabetico tenendo conto delle varie localizzazioni,
+ usando \funcm{strcoll} al posto di \funcm{strcmp}.} anche
+\func{versionsort}, che ordina i nomi tenendo conto del numero di versione
+(cioè qualcosa per cui \texttt{file10} viene comunque dopo \texttt{file4}.)
\begin{figure}[!htbp]
\footnotesize \centering
la directory corrente (vale a dire ``\texttt{.}'') e tornarvi in seguito con
\func{fchdir}.
-Una seconda usata per ottenere la directory di lavoro è \code{char
+Una seconda funzione usata per ottenere la directory di lavoro è \code{char
*get\_current\_dir\_name(void)} che è sostanzialmente equivalente ad una
\code{getcwd(NULL, 0)}, con la sola differenza che essa ritorna il valore
della variabile di ambiente \envvar{PWD}, che essendo costruita dalla shell
-può contenere un \textit{pathname} comprendente anche dei link
+può contenere un \textit{pathname} comprendente anche dei collegamenti
simbolici. Usando \func{getcwd} infatti, essendo il \textit{pathname} ricavato
risalendo all'indietro l'albero della directory, si perderebbe traccia di ogni
-passaggio attraverso eventuali link simbolici.
+passaggio attraverso eventuali collegamenti simbolici.
Per cambiare la directory di lavoro si può usare la funzione \funcd{chdir}
(equivalente del comando di shell \cmd{cd}) il cui nome sta appunto per
\index{directory~di~lavoro|)}
+\subsection{La creazione di file speciali}
+\label{sec:file_mknod}
+
+\index{file!di~dispositivo|(}
+
+Finora abbiamo parlato esclusivamente di file, directory e link simbolici; in
+sez.~\ref{sec:file_file_types} abbiamo visto però che il sistema prevede pure
+degli altri tipi di file speciali, come i file di dispositivo, le fifo ed i
+socket (questi ultimi sono un caso a parte, essendo associati anche alla
+comunicazione via rete, per cui ci saranno trattati in dettaglio a partire da
+cap.~\ref{cha:socket_intro}).
+
+La manipolazione delle caratteristiche di questi diversi tipi di file e la
+loro cancellazione può essere effettuata con le stesse funzioni che operano
+sui file regolari; ma quando li si devono creare sono necessarie delle
+funzioni apposite. La prima di queste funzioni è \funcd{mknod}, il cui
+prototipo è:
+\begin{functions}
+ \headdecl{sys/types.h}
+ \headdecl{sys/stat.h}
+ \headdecl{fcntl.h}
+ \headdecl{unistd.h}
+ \funcdecl{int mknod(const char *pathname, mode\_t mode, dev\_t dev)}
+
+ Crea un \textit{inode} del tipo specificato sul filesystem.
+
+ \bodydesc{La funzione restituisce zero in caso di successo e -1 per un
+ errore, nel qual caso \var{errno} assumerà i valori:
+ \begin{errlist}
+ \item[\errcode{EPERM}] non si hanno privilegi sufficienti a creare
+ l'\texttt{inode}, o il filesystem su cui si è cercato di
+ creare \param{pathname} non supporta l'operazione.
+ \item[\errcode{EINVAL}] il valore di \param{mode} non indica un file, una
+ fifo, un socket o un dispositivo.
+ \item[\errcode{EEXIST}] \param{pathname} esiste già o è un link simbolico.
+ \end{errlist}
+ ed inoltre anche \errval{EFAULT}, \errval{EACCES}, \errval{ENAMETOOLONG},
+ \errval{ENOENT}, \errval{ENOTDIR}, \errval{ENOMEM}, \errval{ELOOP},
+ \errval{ENOSPC}, \errval{EROFS}.}
+\end{functions}
+
+La funzione, come suggerisce il nome, permette di creare un ``\textsl{nodo}''
+sul filesystem, e viene in genere utilizzata per creare i file di dispositivo,
+ma si può usare anche per creare file regolari. L'argomento
+\param{mode} specifica sia il tipo di file che si vuole creare che i relativi
+permessi, secondo i valori riportati in tab.~\ref{tab:file_mode_flags}, che
+vanno combinati con un OR binario. I permessi sono comunque modificati nella
+maniera usuale dal valore di \itindex{umask} \textit{umask} (si veda
+sez.~\ref{sec:file_perm_management}).
+
+Per il tipo di file può essere specificato solo uno fra i seguenti valori:
+\const{S\_IFREG} per un file regolare (che sarà creato vuoto),
+\const{S\_IFBLK} per un dispositivo a blocchi, \const{S\_IFCHR} per un
+dispositivo a caratteri, \const{S\_IFSOCK} per un socket e \const{S\_IFIFO}
+per una fifo;\footnote{con Linux la funzione non può essere usata per creare
+ directory o link simbolici, si dovranno usare le funzioni \func{mkdir} e
+ \func{symlink} a questo dedicate.} un valore diverso comporterà l'errore
+\errcode{EINVAL}.
+
+Qualora si sia specificato in \param{mode} un file di dispositivo (vale a dire
+o \const{S\_IFBLK} o \const{S\_IFCHR}), il valore di \param{dev} dovrà essere
+usato per indicare a quale dispositivo si fa riferimento, altrimenti il suo
+valore verrà ignorato. Solo l'amministratore può creare un file di
+dispositivo usando questa funzione (il processo deve avere la
+\itindex{capabilities} \textit{capability} \const{CAP\_MKNOD}), ma in
+Linux\footnote{questo è un comportamento specifico di Linux, la funzione non è
+ prevista dallo standard POSIX.1 originale, mentre è presente in SVr4 e
+ 4.4BSD, ma esistono differenze nei comportamenti e nei codici di errore,
+ tanto che questa è stata introdotta in POSIX.1-2001 con una nota che la
+ definisce portabile solo quando viene usata per creare delle fifo, ma
+ comunque deprecata essendo utilizzabile a tale scopo la specifica
+ \func{mkfifo}.} l'uso per la creazione di un file ordinario, di una fifo o
+di un socket è consentito anche agli utenti normali.
+
+I nuovi \itindex{inode} \textit{inode} creati con \func{mknod} apparterranno
+al proprietario e al gruppo del processo che li ha creati, a meno che non si
+sia attivato il bit \acr{sgid} per la directory o sia stata attivata la
+semantica BSD per il filesystem (si veda
+sez.~\ref{sec:file_ownership_management}) in cui si va a creare
+\itindex{inode} l'\textit{inode}.
+
+Nella creazione di un file di dispositivo occorre poi specificare
+correttamente il valore di \param{dev}; questo infatti è di tipo
+\type{dev\_t}, che è un tipo primitivo (vedi
+tab.~\ref{tab:intro_primitive_types}) riservato per indicare un
+\textsl{numero} di dispositivo; il kernel infatti identifica ciascun
+dispositivo con un valore numerico. Originariamente questo era un intero a 16
+bit diviso in due parti di 8 bit chiamate rispettivamente
+\itindex{major~number} \textit{major number} e \itindex{minor~number}
+\textit{minor number}, che sono poi i due numeri mostrati dal comando
+\texttt{ls -l} al posto della dimensione quando lo si esegue su un file di
+dispositivo.
+
+Il \itindex{major~number} \textit{major number} identifica una classe di
+dispositivi (ad esempio la seriale, o i dischi IDE) e serve in sostanza per
+indicare al kernel quale è il modulo che gestisce quella classe di
+dispositivi; per identificare uno specifico dispositivo di quella classe (ad
+esempio una singola porta seriale, o una partizione di un disco) si usa invece
+il \itindex{minor~number} \textit{minor number}. L'elenco aggiornato di questi
+numeri con le relative corrispondenze ai vari dispositivi può essere trovato
+nel file \texttt{Documentation/devices.txt} allegato alla documentazione dei
+sorgenti del kernel.
+
+Data la crescita nel numero di dispositivi supportati, ben presto il limite
+massimo di 256 si è rivelato troppo basso, e nel passaggio dai kernel della
+serie 2.4 alla serie 2.6 è stata aumentata a 32 bit la dimensione del tipo
+\type{dev\_t}, con delle dimensioni passate a 12 bit per il
+\itindex{major~number} \textit{major number} e 20 bit per il
+\itindex{minor~number} \textit{minor number}. La transizione però ha anche
+comportato il passaggio di \type{dev\_t} a \index{tipo!opaco} tipo opaco, e la
+necessità di specificare il numero tramite delle opportune macro, così da non
+avere problemi di compatibilità con eventuali ulteriori estensioni.
+
+Le macro sono definite nel file \headfile{sys/sysmacros.h}, che viene
+automaticamente incluso quando si include \headfile{sys/types.h}; si possono
+pertanto ottenere i valori del \itindex{major~number} \textit{major number} e
+\itindex{minor~number} \textit{minor number} di un dispositivo rispettivamente
+con le macro \macro{major} e \macro{minor}:
+\begin{functions}
+ \headdecl{sys/types.h}
+ \funcdecl{int \macro{major}(dev\_t dev)}
+ Restituisce il \itindex{major~number} \textit{major number} del dispositivo
+ \param{dev}.
+
+ \funcdecl{int \macro{minor}(dev\_t dev)}
+ Restituisce il \itindex{minor~number} \textit{minor number} del dispositivo
+ \param{dev}.
+\end{functions}
+\noindent mentre una volta che siano noti \itindex{major~number} \textit{major
+ number} e \itindex{minor~number} \textit{minor number} si potrà costruire il
+relativo identificativo con la macro \macro{makedev}:
+\begin{functions}
+ \headdecl{sys/types.h}
+ \funcdecl{dev\_t \macro{minor}(int major, int minor)}
+
+ Restituisce l'identificativo di un dispositivo dati \itindex{major~number}
+ \textit{major number} e \itindex{minor~number} \textit{minor number}.
+\end{functions}
+
+\index{file!di~dispositivo|)}
+
+Infine con lo standard POSIX.1-2001 è stata introdotta una funzione specifica
+per creare una fifo (tratteremo le fifo in in sez.~\ref{sec:ipc_named_pipe});
+la funzione è \funcd{mkfifo} ed il suo prototipo è:
+\begin{functions}
+ \headdecl{sys/types.h} \headdecl{sys/stat.h}
+
+ \funcdecl{int mkfifo(const char *pathname, mode\_t mode)}
+
+ Crea una fifo.
+
+ \bodydesc{La funzione restituisce zero in caso di successo e -1 per un
+ errore, nel qual caso \var{errno} assumerà i valori \errval{EACCES},
+ \errval{EEXIST}, \errval{ENAMETOOLONG}, \errval{ENOENT}, \errval{ENOSPC},
+ \errval{ENOTDIR} e \errval{EROFS}.}
+\end{functions}
+
+La funzione crea la fifo \param{pathname} con i permessi \param{mode}. Come
+per \func{mknod} il file \param{pathname} non deve esistere (neanche come link
+simbolico); al solito i permessi specificati da \param{mode} vengono
+modificati dal valore di \itindex{umask} \textit{umask}.
+
+
\subsection{I file temporanei}
\label{sec:file_temp_file}
\itindex{race~condition} \textit{race condition} (si ricordi quanto visto in
sez.~\ref{sec:proc_race_cond}).
-Le \acr{glibc} provvedono varie funzioni per generare nomi di file temporanei,
+La \acr{glibc} provvede varie funzioni per generare nomi di file temporanei,
di cui si abbia certezza di unicità al momento della generazione; storicamente
la prima di queste funzioni create a questo scopo era
\funcd{tmpnam},\footnote{la funzione è stata deprecata nella revisione
La funzione restituisce direttamente uno stream già aperto (in modalità
\code{r+b}, si veda sez.~\ref{sec:file_fopen}) e pronto per l'uso, che viene
automaticamente cancellato alla sua chiusura o all'uscita dal programma. Lo
-standard non specifica in quale directory verrà aperto il file, ma le
-\acr{glibc} prima tentano con \const{P\_tmpdir} e poi con \file{/tmp}. Questa
+standard non specifica in quale directory verrà aperto il file, ma la
+\acr{glibc} prima tenta con \const{P\_tmpdir} e poi con \file{/tmp}. Questa
funzione è \index{funzioni!rientranti} rientrante e non soffre di problemi di
\itindex{race~condition} \textit{race condition}.
certezza di essere stati i creatori del file, i cui permessi (si veda
sez.~\ref{sec:file_perm_overview}) sono impostati al valore \code{0600}
(lettura e scrittura solo per il proprietario).\footnote{questo è vero a
- partire dalle \acr{glibc} 2.0.7, le versioni precedenti delle \acr{glibc} e
+ partire dalla \acr{glibc} 2.0.7, le versioni precedenti della \acr{glibc} e
le vecchie \acr{libc5} e \acr{libc4} usavano il valore \code{0666} che
permetteva a chiunque di leggere e scrivere i contenuti del file.} Di
questa funzione esiste una variante \funcd{mkostemp}, introdotta
In OpenBSD è stata introdotta un'altra funzione simile alle precedenti,
\funcd{mkdtemp}, che crea invece una directory temporanea;\footnote{la
- funzione è stata introdotta nelle \acr{glibc} a partire dalla versione
+ funzione è stata introdotta nella \acr{glibc} a partire dalla versione
2.1.91 ed inserita nello standard POSIX.1-2008.} il suo prototipo è:
\begin{prototype}{stlib.h}{char *mkdtemp(char *template)}
Genera una directory temporanea.
Queste due funzioni sono una estensione definita in una recente revisione
dello standard POSIX (la POSIX.1-2008); sono state introdotte a partire dal
-kernel 2.6.22, e supportate dalle \acr{glibc} a partire dalla versione
+kernel 2.6.22, e supportate dalla \acr{glibc} a partire dalla versione
2.6.\footnote{in precedenza, a partire dal kernel 2.6.16, era stata introdotta
la funzione \funcm{futimesat} seguendo una bozza della revisione dello
standard poi modificata, questa funzione, sostituita da \func{utimensat}, è
\end{basedescript}
Le funzioni per la gestione degli attributi estesi, come altre funzioni di
-gestione avanzate specifiche di Linux, non fanno parte delle \acr{glibc}, e
+gestione avanzate specifiche di Linux, non fanno parte della \acr{glibc}, e
sono fornite da una apposita libreria, \texttt{libattr}, che deve essere
installata a parte;\footnote{la versione corrente della libreria è
\texttt{libattr1}.} pertanto se un programma le utilizza si dovrà indicare
delle ACL e presenta ai programmi una interfaccia che fa riferimento allo
standard POSIX 1003.1e.
-Anche in questo caso le funzioni di questa libreria non fanno parte delle
+Anche in questo caso le funzioni di questa libreria non fanno parte della
\acr{glibc} e devono essere installate a parte;\footnote{la versione corrente
della libreria è \texttt{libacl1}, e nel caso si usi Debian la si può
installare con il pacchetto omonimo e con il collegato \texttt{libacl1-dev}
\const{CAP\_SYS\_ADMIN}, che copre una serie di operazioni amministrative,
come impostare le quote disco (vedi sez.\ref{sec:disk_quota}), attivare e
disattivare la swap, montare, rimontare e smontare filesystem (vedi
-sez.~\ref{sec:sys_file_config}), effettuare operazioni di controllo su
+sez.~\ref{sec:filesystem_mounting}), effettuare operazioni di controllo su
qualunque oggetto dell'IPC di SysV (vedi sez.~\ref{sec:ipc_sysv}), operare
sugli attributi estesi dei file di classe \texttt{security} o \texttt{trusted}
-(vedi sez.~\ref{sec:file_xattr}), specificare un \ids{UID} arbitrario
-nella trasmissione delle credenziali dei socket (vedi
+(vedi sez.~\ref{sec:file_xattr}), specificare un \ids{UID} arbitrario nella
+trasmissione delle credenziali dei socket (vedi
sez.~\ref{sec:socket_credential_xxx}), assegnare classi privilegiate
(\const{IOPRIO\_CLASS\_RT} e prima del kernel 2.6.25 anche
\const{IOPRIO\_CLASS\_IDLE}) per lo scheduling dell'I/O (vedi
garantiscono la stabilità nell'interfaccia, è sempre opportuno effettuare la
gestione delle \textit{capabilities} utilizzando le funzioni di libreria a
questo dedicate. Queste funzioni, che seguono quanto previsto nelle bozze
-dello standard POSIX.1e, non fanno parte delle \acr{glibc} e sono fornite in
+dello standard POSIX.1e, non fanno parte della \acr{glibc} e sono fornite in
una libreria a parte,\footnote{la libreria è \texttt{libcap2}, nel caso di
Debian può essere installata con il pacchetto omonimo.} pertanto se un
programma le utilizza si dovrà indicare esplicitamente l'uso della suddetta
% LocalWords: mountflags NODEV ENXIO dummy devfs magic MGC RDONLY NOSUID MOVE
% LocalWords: NOEXEC SYNCHRONOUS REMOUNT MANDLOCK NODIRATIME umount MNT statfs
% LocalWords: fstatfs fstab mntent ino bound orig new setpcap metadati sysfs
+% LocalWords: bind DIRSYNC lsattr Hierarchy FHS SHARED UNBINDABLE shared REC
+% LocalWords: subtree SILENT log unbindable BUSY EAGAIN EXPIRE DETACH NOFOLLOW
+% LocalWords: lazy encfs sshfs setfsent getfsent getfsfile getfsspec endfsent
+% LocalWords: setmntent getmntent addmntent endmntent hasmntopt
%%% Local Variables:
%%% mode: latex
%%% TeX-master: "gapil"
%%% End:
-% LocalWords: bind DIRSYNC lsattr Hierarchy FHS SHARED UNBINDABLE shared REC
-% LocalWords: subtree SILENT log unbindable BUSY EAGAIN EXPIRE DETACH NOFOLLOW
-% LocalWords: lazy
Come accennato nella sezione precedente ogni processo viene identificato dal
sistema da un numero identificativo univoco, il \textit{process ID} o
\ids{PID}. Questo è un tipo di dato standard, \type{pid\_t} che in genere è un
-intero con segno (nel caso di Linux e delle \acr{glibc} il tipo usato è
+intero con segno (nel caso di Linux e della \acr{glibc} il tipo usato è
\ctyp{int}).
Il \ids{PID} viene assegnato in forma progressiva ogni volta che un nuovo
Tutti i processi inoltre memorizzano anche il \ids{PID} del genitore da cui
sono stati creati, questo viene chiamato in genere \ids{PPID} (da
\itindex{Parent~Process~ID~(PPID)} \textit{Parent Process ID}). Questi due
-identificativi possono essere ottenuti usando le due funzioni \funcd{getpid} e
-\funcd{getppid}, i cui prototipi sono:
+identificativi possono essere ottenuti usando le due funzioni di sistema
+\funcd{getpid} e \funcd{getppid}, i cui prototipi sono:
\begin{funcproto}{
\fhead{sys/types.h}
\subsection{La funzione \func{fork} e le funzioni di creazione dei processi}
\label{sec:proc_fork}
-La funzione \funcd{fork} è la funzione fondamentale della gestione dei
-processi: come si è detto tradizionalmente l'unico modo di creare un nuovo
+La funzione di sistema \funcd{fork} è la funzione fondamentale della gestione
+dei processi: come si è detto tradizionalmente l'unico modo di creare un nuovo
processo era attraverso l'uso di questa funzione,\footnote{in realtà oggi la
\textit{system call} usata da Linux per creare nuovi processi è \func{clone}
- (vedi \ref{sec:process_clone}), anche perché a partire dalle \acr{glibc}
+ (vedi \ref{sec:process_clone}), anche perché a partire dalla \acr{glibc}
2.3.3 non viene più usata la \textit{system call} originale, ma la stessa
\func{fork} viene implementata tramite \func{clone}, cosa che consente una
migliore interazione coi \textit{thread}.} essa quindi riveste un ruolo
Si è già sottolineato al paragrafo precedente come in questo caso diventi
necessario gestire esplicitamente la conclusione dei figli onde evitare di
riempire di \itindex{zombie} \textit{zombie} la tabella dei
-processi. Tratteremo in questa sezione le funzioni deputate a questo compito;
-la prima è \funcd{wait} ed il suo prototipo è:
+processi. Tratteremo in questa sezione le funzioni di sistema deputate a
+questo compito; la prima è \funcd{wait} ed il suo prototipo è:
\begin{funcproto}{
\fhead{sys/types.h}
sez.~\ref{sec:sess_job_control}). Dato che è possibile ottenere lo stesso
comportamento di \func{wait}\footnote{in effetti il codice
\code{wait(\&status)} è del tutto equivalente a \code{waitpid(WAIT\_ANY,
- \&status, 0)}.} si consiglia di utilizzare sempre questa nuova funzione,
-\funcd{waitpid}, il cui prototipo è:
+ \&status, 0)}.} si consiglia di utilizzare sempre questa nuova funzione di
+sistema, \funcd{waitpid}, il cui prototipo è:
\begin{funcproto}{
\fhead{sys/types.h}
A partire dal kernel 2.6.9, sempre in conformità allo standard POSIX.1-2001, è
stata introdotta una nuova funzione di attesa che consente di avere un
controllo molto più preciso sui possibili cambiamenti di stato dei processi
-figli e più dettagli sullo stato di uscita; la funzione è \funcd{waitid} ed il
-suo prototipo è:
+figli e più dettagli sullo stato di uscita; la funzione di sistema è
+\funcd{waitid} ed il suo prototipo è:
\begin{funcproto}{
\fhead{sys/types.h}
precedenti ma che prevedono un ulteriore argomento attraverso il quale il
kernel può restituire al padre informazioni sulle risorse (vedi
sez.~\ref{sec:sys_res_limits}) usate dal processo terminato e dai vari figli.
-Le due funzioni sono \funcd{wait3} e \funcd{wait4}, che diventano accessibili
-definendo la macro \macro{\_USE\_BSD}, i loro prototipi sono:
+Le due funzioni di sistema sono \funcd{wait3} e \funcd{wait4}, che diventano
+accessibili definendo la macro \macro{\_USE\_BSD}, i loro prototipi sono:
\begin{funcproto}{
\fhead{sys/types.h}
programma è in formato ELF per caricare le librerie dinamiche viene usato
l'interprete indicato nel segmento \const{PT\_INTERP} previsto dal formato
stesso, in genere questo è \sysfile{/lib/ld-linux.so.1} per programmi
-collegati con le \acr{libc5}, e \sysfile{/lib/ld-linux.so.2} per programmi
-collegati con le \acr{glibc}.
+collegati con la \acr{libc5}, e \sysfile{/lib/ld-linux.so.2} per programmi
+collegati con la \acr{glibc}.
Infine nel caso il programma che si vuole eseguire sia uno script e non un
binario, questo deve essere un file di testo che deve iniziare con una linea
Come nel caso del \ids{PID} e del \ids{PPID}, anche tutti questi
identificatori possono essere ottenuti da un programma attraverso altrettante
-funzioni di lettura, queste sono \funcd{getuid}, \funcd{geteuid},
-\funcd{getgid} e \funcd{getegid}, ed i loro prototipi sono:
+funzioni di sistema dedicate alla loro lettura, queste sono \funcd{getuid},
+\funcd{geteuid}, \funcd{getgid} e \funcd{getegid}, ed i loro prototipi sono:
\begin{funcproto}{
\fhead{unistd.h}
\subsection{Le funzioni di gestione degli identificatori dei processi}
\label{sec:proc_setuid}
-Le due funzioni più comuni che vengono usate per cambiare identità (cioè
-utente e gruppo di appartenenza) ad un processo sono rispettivamente
-\funcd{setuid} e \funcd{setgid}; come accennato in
-sez.~\ref{sec:proc_access_id} in Linux esse seguono la semantica POSIX che
-prevede l'esistenza dell'\ids{UID} salvato e del \ids{GID} salvato; i loro
-prototipi sono:
+Le funzioni di sistema più comuni che vengono usate per cambiare identità
+(cioè utente e gruppo di appartenenza) ad un processo, e che come accennato in
+sez.~\ref{sec:proc_access_id} seguono la semantica POSIX che prevede
+l'esistenza dell'\ids{UID} salvato e del \ids{GID} salvato, sono
+rispettivamente \funcd{setuid} e \funcd{setgid}; i loro prototipi sono:
\begin{funcproto}{
\fhead{unistd.h}
l'\ids{UID} effettivo del processo per cedere i privilegi occorre
ricorrere ad altre funzioni.
-Le due funzioni \funcd{setreuid} e \funcd{setregid} derivano da BSD che, non
-supportando (almeno fino alla versione 4.3+BSD) gli identificatori del gruppo
-\textit{saved}, le usa per poter scambiare fra di loro \textit{effective} e
-\textit{real}; i rispettivi prototipi sono:
+Le due funzioni di sistema \funcd{setreuid} e \funcd{setregid} derivano da BSD
+che, non supportando (almeno fino alla versione 4.3+BSD) gli identificatori
+del gruppo \textit{saved}, le usa per poter scambiare fra di loro
+\textit{effective} e \textit{real}; i rispettivi prototipi sono:
\begin{funcproto}{
\fhead{unistd.h}
diverso da quello dall'\ids{UID} reale corrente, l'\ids{UID} salvato viene
automaticamente uniformato al valore dell'\ids{UID} effettivo.
-Altre due funzioni, \funcd{seteuid} e \funcd{setegid}, sono un'estensione
-dello standard POSIX.1, ma sono comunque supportate dalla maggior parte degli
-Unix, esse vengono usate per cambiare gli identificatori del gruppo
-\textit{effective} ed i loro prototipi sono:
+Altre due funzioni di sistema, \funcd{seteuid} e \funcd{setegid}, sono
+un'estensione dello standard POSIX.1, ma sono comunque supportate dalla
+maggior parte degli Unix, esse vengono usate per cambiare gli identificatori
+del gruppo \textit{effective} ed i loro prototipi sono:
\begin{funcproto}{
\fhead{unistd.h}
dato che l'uso normale di \func{setuid} comporta l'impostazione di tutti gli
identificatori.
-Le due funzioni \funcd{setresuid} e \funcd{setresgid} sono invece
+Le due funzioni di sistema \funcd{setresuid} e \funcd{setresgid} sono invece
un'estensione introdotta in Linux (a partire dal kernel 2.1.44) e permettono
un completo controllo su tutti e tre i gruppi di identificatori
(\textit{real}, \textit{effective} e \textit{saved}), i loro prototipi sono:
di $-1$ per un qualunque argomento lascia inalterato l'identificatore
corrispondente.
-Per queste funzioni esistono anche due controparti, \funcd{getresuid} e
-\funcd{getresgid},\footnote{le funzioni non sono standard, anche se appaiono
- in altri kernel, su Linux sono presenti dal kernel 2.1.44 e con le versioni
- della \acr{glibc} a partire dalla 2.3.2, definendo la macro
- \macro{\_GNU\_SOURCE}.} che permettono di leggere in blocco i vari
+Per queste funzioni di sistema esistono anche due controparti,
+\funcd{getresuid} e \funcd{getresgid},\footnote{le funzioni non sono standard,
+ anche se appaiono in altri kernel, su Linux sono presenti dal kernel 2.1.44
+ e con le versioni della \acr{glibc} a partire dalla 2.3.2, definendo la
+ macro \macro{\_GNU\_SOURCE}.} che permettono di leggere in blocco i vari
identificatori; i loro prototipi sono:
\begin{funcproto}{
originari per quanto riguarda tutti gli altri controlli di accesso, così che
l'utente non possa inviare segnali al server NFS.
-Le due funzioni usate per cambiare questi identificatori sono \funcd{setfsuid}
-e \funcd{setfsgid}, ed ovviamente sono specifiche di Linux e non devono essere
-usate se si intendono scrivere programmi portabili; i loro prototipi sono:
+Le due funzioni di sistema usate per cambiare questi identificatori sono
+\funcd{setfsuid} e \funcd{setfsgid}, ed ovviamente sono specifiche di Linux e
+non devono essere usate se si intendono scrivere programmi portabili; i loro
+prototipi sono:
\begin{funcproto}{
\fhead{sys/fsuid.h}
\texttt{\_SC\_NGROUPS\_MAX}.} in aggiunta al gruppo primario; questi vengono
ereditati dal processo padre e possono essere cambiati con queste funzioni.
-La funzione che permette di leggere i gruppi supplementari associati ad un
-processo è \funcd{getgroups}; questa funzione è definita nello standard
-POSIX.1, ed il suo prototipo è:
+La funzione di sistema che permette di leggere i gruppi supplementari
+associati ad un processo è \funcd{getgroups}; questa funzione è definita nello
+standard POSIX.1, ed il suo prototipo è:
\begin{funcproto}{
\fhead{sys/types.h}
Infine per impostare i gruppi supplementari di un processo ci sono due
funzioni, che possono essere usate solo se si hanno i privilegi di
amministratore.\footnote{e più precisamente se si ha la \itindex{capabilities}
- \textit{capability} \macro{CAP\_SETGID}.} La prima delle due è
-\funcd{setgroups},\footnote{la funzione è definita in BSD e SRv4, ma a
- differenza di \func{getgroups} non è stata inclusa in POSIX.1-2001, per
+ \textit{capability} \macro{CAP\_SETGID}.} La prima delle due è la funzione
+di sistema \funcd{setgroups},\footnote{la funzione è definita in BSD e SRv4,
+ ma a differenza di \func{getgroups} non è stata inclusa in POSIX.1-2001, per
poterla utilizzare deve essere definita la macro \macro{\_BSD\_SOURCE}.} ed
il suo prototipo è:
che si possono impostare è un parametro di sistema, che può essere ricavato
con le modalità spiegate in sez.~\ref{sec:sys_characteristics}.
-Se invece si vogliono impostare i gruppi supplementari del processo a quelli di
-un utente specifico, si può usare \funcd{initgroups} il cui prototipo è:
+Se invece si vogliono impostare i gruppi supplementari del processo a quelli
+di un utente specifico, si può usare la funzione \funcd{initgroups} il cui
+prototipo è:
\begin{funcproto}{
\fhead{sys/types.h}
di adeguati privilegi, di diminuire un valore di \textit{nice} precedentemente
innalzato.
-Fino alle \acr{glibc} 2.2.4 la funzione di libreria riportava direttamente il
+Fino alla \acr{glibc} 2.2.4 la funzione di libreria riportava direttamente il
risultato dalla \textit{system call}, violando lo standard, per cui per
ottenere il nuovo valore occorreva una successiva chiamata alla funzione
\func{getpriority}. A partire dalla \acr{glibc} 2.2.4 \func{nice} è stata
verificarne il valore quando \func{nice} restituisce $-1$.
Per leggere il valore di \textit{nice} di un processo occorre usare la
-funzione \funcd{getpriority}, derivata da BSD; il suo prototipo è:
+funzione di sistema \funcd{getpriority}, derivata da BSD; il suo prototipo è:
\begin{funcproto}{
\fhead{sys/time.h}
quando si ottiene un valore di ritorno uguale a $-1$ per verificare che essa
resti uguale a zero.
-Analoga a \func{getpriority} è la funzione \funcd{setpriority} che permette di
-impostare la priorità di uno o più processi; il suo prototipo è:
+Analoga a \func{getpriority} è la funzione di sistema \funcd{setpriority} che
+permette di impostare la priorità di uno o più processi; il suo prototipo è:
\begin{funcproto}{
\fhead{sys/time.h}
Lo standard POSIX.1-2001 prevede una funzione che consenta sia di modificare
le politiche di \textit{scheduling}, passando da \textit{real-time} a
ordinarie o viceversa, che di specificare, in caso di politiche
-\textit{real-time}, la eventuale priorità statica; la funzione è
+\textit{real-time}, la eventuale priorità statica; la funzione di sistema è
\funcd{sched\_setscheduler} ed il suo prototipo è:
\begin{funcproto}{
impostato con le funzioni viste in precedenza.
Lo standard POSIX.1b prevede comunque che l'intervallo dei valori delle
-priorità statiche possa essere ottenuto tramite le due funzioni
+priorità statiche possa essere ottenuto con le funzioni di sistema
\funcd{sched\_get\_priority\_max} e \funcd{sched\_get\_priority\_min}, i cui
prototipi sono:
politica ordinaria.
Se si intende operare solo sulla priorità statica di un processo si possono
-usare le due funzioni \funcd{sched\_setparam} e \funcd{sched\_getparam} che
-consentono rispettivamente di impostarne e leggerne il valore, i loro
-prototipi sono:
+usare le due funzioni di sistema \funcd{sched\_setparam} e
+\funcd{sched\_getparam} che consentono rispettivamente di impostarne e
+leggerne il valore, i loro prototipi sono:
-\begin{funcproto}{
+\begin{funcproto}{
\fhead{sched.h}
\fdecl{int sched\_setparam(pid\_t pid, const struct sched\_param *param)}
\fdesc{Imposta la priorità statica di un processo.}
file} \headfile{sched.h}.
Se invece si vuole sapere quale è politica di \textit{scheduling} di un
-processo si può usare la funzione \funcd{sched\_getscheduler}, il cui
-prototipo è:
+processo si può usare la funzione di sistema \funcd{sched\_getscheduler}, il
+cui prototipo è:
\begin{funcproto}{
\fhead{sched.h}
processo specificato dall'argomento \param{pid}, se questo è nullo viene
restituito il valore relativo al processo chiamante.
-L'ultima funzione che permette di leggere le informazioni relative ai processi
-real-time è \funcd{sched\_rr\_get\_interval}, che permette di ottenere la
-lunghezza della \textit{time-slice} usata dalla politica \textit{round robin};
-il suo prototipo è:
+L'ultima funzione di sistema che permette di leggere le informazioni relative
+ai processi real-time è \funcd{sched\_rr\_get\_interval}, che permette di
+ottenere la lunghezza della \textit{time-slice} usata dalla politica
+\textit{round robin}; il suo prototipo è:
\begin{funcproto}{
\fhead{sched.h}
\textit{real-time}.
Come accennato ogni processo può rilasciare volontariamente la CPU in modo da
-consentire agli altri processi di essere eseguiti; la funzione che consente di
-fare tutto ciò è \funcd{sched\_yield}, il cui prototipo è:
+consentire agli altri processi di essere eseguiti; la funzione di sistema che
+consente di fare tutto questo è \funcd{sched\_yield}, il cui prototipo è:
\begin{funcproto}{
\fhead{sched.h}
solo una preferenza, non un requisito assoluto.} e per poter risolvere
questo tipo di problematiche nei nuovi kernel\footnote{le due \textit{system
call} per la gestione della \textit{CPU affinity} sono state introdotte
- nel kernel 2.5.8, e le funzioni di libreria nelle \textsl{glibc} 2.3.} è
-stata introdotta l'opportuna infrastruttura ed una nuova \textit{system call}
-che permette di impostare su quali processori far eseguire un determinato
-processo attraverso una \textsl{maschera di affinità}. La corrispondente
-funzione di libreria è \funcd{sched\_setaffinity} ed il suo prototipo è:
+ nel kernel 2.5.8, e le corrispondenti funzioni di sistema nella
+ \textsl{glibc} 2.3.} è stata introdotta l'opportuna infrastruttura ed una
+nuova \textit{system call} che permette di impostare su quali processori far
+eseguire un determinato processo attraverso una \textsl{maschera di
+ affinità}. La corrispondente funzione di sistema è
+\funcd{sched\_setaffinity} ed il suo prototipo è:
\index{insieme~di~processori|(}
\begin{funcproto}{
\fhead{sched.h}
-\fdecl{int sched\_setaffinity (pid\_t pid, size\_t setsize,
+\fdecl{int sched\_setaffinity(pid\_t pid, size\_t setsize,
cpu\_set\_t *mask)}
\fdesc{Imposta la maschera di affinità di un processo.}
}
ed inoltre anche \errval{EFAULT} nel suo significato generico.}
\end{funcproto}
-Questa funzione e la corrispondente \func{sched\_setaffinity} hanno una storia
+Questa funzione e la corrispondente \func{sched\_getaffinity} hanno una storia
abbastanza complessa, la sottostante \textit{system call} infatti prevede
l'uso di due soli argomenti (per il pid e l'indicazione della maschera dei
processori), che corrispondono al fatto che l'implementazione effettiva usa
-una semplice maschera binaria. Quando le funzioni vennero incluse nelle
+una semplice maschera binaria. Quando le funzioni vennero incluse nella
\acr{glibc} assunsero invece un prototipo simile a quello mostrato però con il
secondo argomento di tipo \ctyp{unsigned int}. A complicare la cosa si
-aggiunge il fatto che nella versione 2.3.3 delle \acr{glibc} detto argomento
+aggiunge il fatto che nella versione 2.3.3 della \acr{glibc} detto argomento
venne stato eliminato, per poi essere ripristinato nella versione 2.3.4 nella
forma attuale.\footnote{pertanto se la vostra pagina di manuale non è
- aggiornata, o usate quella particolare versione delle \acr{glibc}, potrete
+ aggiornata, o usate quella particolare versione della \acr{glibc}, potrete
trovare indicazioni diverse, il prototipo illustrato è quello riportato
nella versione corrente (maggio 2008) delle pagine di manuale e
corrispondente alla definizione presente in \headfile{sched.h}.}
di processore.
Dato che il numero di processori può variare a seconda delle architetture, per
-semplificare l'uso dell'argomento \param{mask} le \acr{glibc} hanno introdotto
-un apposito dato di tipo, \type{cpu\_set\_t},\footnote{questa è una estensione
- specifica delle \acr{glibc}, da attivare definendo la macro
+semplificare l'uso dell'argomento \param{mask} la \acr{glibc} ha introdotto un
+apposito dato di tipo, \type{cpu\_set\_t},\footnote{questa è una estensione
+ specifica della \acr{glibc}, da attivare definendo la macro
\macro{\_GNU\_SOURCE}, non esiste infatti una standardizzazione per questo
tipo di interfaccia e POSIX al momento non prevede nulla al riguardo.} che
permette di identificare un insieme di processori. Il dato è normalmente una
A meno di non aver utilizzato \func{sched\_setaffinity}, in condizioni
ordinarie la maschera di affinità di un processo è preimpostata dal sistema in
modo che esso possa essere eseguito su qualunque processore. Se ne può
-comunque ottenere il valore usando la funzione \funcd{sched\_getaffinity}, il
-cui prototipo è:
+comunque ottenere il valore corrente usando la funzione di sistema
+\funcd{sched\_getaffinity}, il cui prototipo è:
\begin{funcproto}{
\fhead{sched.h}
kernel.
Una volta che si sia impostato lo \textit{scheduler} CFQ ci sono due
-specifiche system call, specifiche di Linux, che consentono di leggere ed
-impostare le priorità di I/O.\footnote{se usate in corrispondenza ad uno
- \textit{scheduler} diverso il loro utilizzo non avrà alcun effetto.} Dato
-che non esiste una interfaccia diretta nelle \acr{glibc} per queste due
+specifiche \textit{system call}, specifiche di Linux, che consentono di
+leggere ed impostare le priorità di I/O.\footnote{se usate in corrispondenza
+ ad uno \textit{scheduler} diverso il loro utilizzo non avrà alcun effetto.}
+Dato che non esiste una interfaccia diretta nella \acr{glibc} per queste due
funzioni\footnote{almeno al momento della scrittura di questa sezione, con la
versione 2.11 della \acr{glibc}.} occorrerà invocarle tramite la funzione
\func{syscall} (come illustrato in sez.~\ref{sec:proc_syscall}). Le due
-funzioni sono \funcd{ioprio\_get} ed \funcd{ioprio\_set}; i rispettivi
-prototipi sono:
+\textit{system call} sono \funcd{ioprio\_get} ed \funcd{ioprio\_set}; i
+rispettivi prototipi sono:
\begin{funcproto}{
\fhead{linux/ioprio.h}
proprietà e caratteristiche particolari dei processi non coperte da esse, per
la cui gestione è stata predisposta una apposita \textit{system call} che
fornisce una interfaccia generica per tutte le operazioni specialistiche. La
-funzione è \funcd{prctl} ed il suo prototipo è:\footnote{la funzione non è
- standardizzata ed è specifica di Linux, anche se ne esiste una analoga in
- IRIX; è stata introdotta con il kernel 2.1.57.}
+funzione di sistema è \funcd{prctl} ed il suo prototipo è:\footnote{la
+ funzione non è standardizzata ed è specifica di Linux, anche se ne esiste
+ una analoga in IRIX; è stata introdotta con il kernel 2.1.57.}
\begin{funcproto}{
\fhead{sys/prctl.h}
\textit{stack} totalmente indipendente da quello del padre.
Dato che l'uso principale della nuova \textit{system call} è quello relativo
-alla creazione dei \textit{thread}, le \acr{glibc} definiscono una funzione di
+alla creazione dei \textit{thread}, la \acr{glibc} definisce una funzione di
libreria con una sintassi diversa, orientata a questo scopo, e la
\textit{system call} resta accessibile solo se invocata esplicitamente come
visto in sez.~\ref{sec:proc_syscall}.\footnote{ed inoltre per questa
parte del programmatore.
In genere le funzioni di libreria non sono rientranti, molte di esse ad
-esempio utilizzano \index{variabili!statiche} variabili statiche, le
-\acr{glibc} però mettono a disposizione due macro di compilatore,
+esempio utilizzano \index{variabili!statiche} variabili statiche, la
+\acr{glibc} però mette a disposizione due macro di compilatore,
\macro{\_REENTRANT} e \macro{\_THREAD\_SAFE}, la cui definizione attiva le
versioni rientranti di varie funzioni di libreria, che sono identificate
aggiungendo il suffisso \code{\_r} al nome della versione normale.