%% intro.tex
%%
-%% Copyright (C) 2000-2011 Simone Piccardi. Permission is granted to
+%% Copyright (C) 2000-2015 Simone Piccardi. Permission is granted to
%% copy, distribute and/or modify this document under the terms of the GNU Free
%% Documentation License, Version 1.1 or any later version published by the
%% Free Software Foundation; with the Invariant Sections being "Un preambolo",
\label{fig:intro_sys_struct}
\end{figure}
-Una parte del kernel, lo \itindex{scheduler} \textit{scheduler}, si occupa di
-stabilire, sulla base di un opportuno calcolo delle priorità e con una
-suddivisione appropriata del tempo di processore, quali fra i vari
-``\textsl{processi}'' presenti nel sistema deve essere eseguito, realizzando
-il cosiddetto \itindex{preemptive~multitasking} \textit{preemptive
+\itindbeg{scheduler}
+
+Una parte del kernel, lo \textit{scheduler}, si occupa di stabilire, sulla
+base di un opportuno calcolo delle priorità e con una suddivisione appropriata
+del tempo di processore, quali fra i vari ``\textsl{processi}'' presenti nel
+sistema deve essere eseguito, realizzando il cosiddetto
+\itindex{preemptive~multitasking} \textit{preemptive
multitasking}.\footnote{si chiama così quella gestione del
\textit{multitasking} in cui è il kernel a decidere a chi assegnare l'uso
della CPU, potendo interrompere l'esecuzione di un processo in qualunque
sez.~\ref{sec:intro_syscall}) che restituiranno il controllo al kernel per
eseguire le operazioni necessarie.
+\itindend{scheduler}
+
La memoria viene sempre gestita dal kernel attraverso il meccanismo della
\index{memoria~virtuale} \textsl{memoria virtuale}, che consente di assegnare
a ciascun processo uno spazio di indirizzi ``\textsl{virtuale}'' (vedi
Le periferiche infine vengono normalmente viste attraverso un'interfaccia
astratta che permette di trattarle come se fossero dei file, secondo uno dei
concetti base della architettura di Unix, per cui ``\textsl{tutto è in file}''
-(\textit{everything is a file}) su cui torneremo in dettaglio in
-cap.~\ref{cha:file_intro}. In realtà questo non è sempre vero (ad esempio non
-lo è per le interfacce di rete) dato che ci sono periferiche che non
+(\textit{everything is a file}) su cui torneremo in
+sez.~\ref{sec:intro_file_dir}. In realtà questo non è sempre vero (ad esempio
+non lo è per le interfacce di rete) dato che ci sono periferiche che non
rispondendo bene a questa astrazione richiedono un'interfaccia diversa. Anche
in questo caso però resta valido il concetto generale che tutto il lavoro di
accesso e gestione delle periferiche a basso livello viene effettuato dal
impossibile, di far eseguire un programma a partire da un computer appena
acceso che appunto non ne contiene nessuno; non è impossibile perché in
realtà c'è un programma iniziale, che è il BIOS.} incaricandosi di caricare
-il kernel in memoria e di farne partire l'esecuzione. A questo punto il
-controllo passerà al kernel, il quale però da parte sua, una volta
-inizializzato opportunamente l'hardware, si limiterà a lanciare un unico
-processo di inizializzazione (che per questo in genere genere si chiama
-\cmd{init}). A questo punto tutto il lavoro verrà eseguito \textit{user space}
-da questo programma, che sua volta si incaricherà di lanciare tutti gli altri,
-fra cui ci sarà quello che si occupa di dialogare con la tastiera e lo schermo
-della console, quello che mette a disposizione un terminale e la
-\textit{shell} da cui inviare i comandi all'utente che si vuole collegare, ed
-in generale tutto quanto necessario ad avere un sistema utilizzabile.
+il kernel in memoria e di farne partire l'esecuzione.
+
+A questo punto il controllo passerà al kernel, il quale però da parte sua, una
+volta inizializzato opportunamente l'hardware, si limiterà a due sole
+operazioni, montare il filesystem radice (torneremo su questo in
+sez.~\ref{sec:file_arch_overview}) e lanciare il primo processo che eseguirà
+il programma di inizializzazione del sistema, che in genere, visto il suo
+scopo, si chiama \cmd{init}.
+
+Una volta lanciato \cmd{init} tutto il lavoro successivo verrà eseguito
+\textit{user space} da questo programma, che sua volta si incaricherà di
+lanciare tutti gli altri programmi, fra cui ci sarà quello che si occupa di
+dialogare con la tastiera e lo schermo della console, quello che mette a
+disposizione un terminale e la \textit{shell} da cui inviare i comandi
+all'utente che si vuole collegare, ed in generale tutto quanto necessario ad
+avere un sistema utilizzabile.
E' da rimarcare come tutto ciò che riguarda l'interazione con l'utente, che
usualmente viene visto come parte del sistema, non abbia in realtà niente a
attraverso dei normali programmi utilizzando le interfacce di programmazione
che il kernel mette a disposizione.
-%Una delle caratteristiche base di unix \`e perci\`o che \`e possibile
-%realizzare un sistema di permessi e controlli che evitano che i programmi
-%eseguano accessi non autorizzati.
-
È per questo motivo che quando ci si riferisce al sistema nella sua interezza
viene spesso sottolineato come sia corretto parlare di ``GNU/Linux'' e non di
Linux; da solo infatti il kernel non è sufficiente, quello che costruisce un
\textit{system call} sono poi state codificate da vari standard, che
esamineremo brevemente in sez.~\ref{sec:intro_standard}.
-Normalmente ciascuna chiamata al sistema fornita dal kernel viene associata ad
-una funzione con lo stesso nome definita all'interno della libreria
+Normalmente ciascuna \textit{system call} fornita dal kernel viene associata
+ad una funzione con lo stesso nome definita all'interno della libreria
fondamentale del sistema, quella che viene chiamata \textsl{Libreria Standard
del C} (\textit{C Standard Library}) in ragione del fatto che il primo
kernel Unix e tutti i programmi eseguiti su di esso vennero scritti in C,
-usando le librerie di questo linguaggio. Questa libreria, oltre alle
-interfacce delle \textit{system call}, contiene anche tutta una serie di
-ulteriori funzioni di utilità che vengono comunemente usate nella
-programmazione e sono definite nei vari standard che documentano le interfacce
-di programmazione di un sistema unix-like.
-
-Questo concetto è importante da tener presente perché programmare in Linux
-significa anzitutto essere in grado di usare le funzioni fornite dalla
-\textsl{Libreria Standard del C}, in quanto né il kernel, né il linguaggio C
-implementano direttamente operazioni ordinarie come l'allocazione dinamica
-della memoria, l'input/output bufferizzato sui file o la manipolazione delle
-stringhe, che sono comunemente usate da qualunque programma.
+usando le librerie di questo linguaggio. In seguito faremo riferimento alle
+funzioni di questa libreria che si interfacciano alle \textit{system call}
+come ``\textsl{funzioni di sistema}''.
+
+Questa libreria infatti, oltre alle interfacce delle \textit{system call},
+contiene anche tutta una serie di ulteriori funzioni di utilità che vengono
+comunemente usate nella programmazione e sono definite nei vari standard che
+documentano le interfacce di programmazione di un sistema unix-like. Questo
+concetto è importante da tener presente perché programmare in Linux significa
+anche essere in grado di usare le funzioni fornite dalla \textsl{Libreria
+ Standard del C}, in quanto né il kernel, né il linguaggio C implementano
+direttamente operazioni ordinarie come l'allocazione dinamica della memoria,
+l'input/output bufferizzato sui file o la manipolazione delle stringhe, la
+matematica in virgola mobile, che sono comunemente usate da qualunque
+programma.
Tutto ciò mette nuovamente in evidenza il fatto che nella stragrande
maggioranza dei casi si dovrebbe usare il nome GNU/Linux in quanto una parte
la cui corrispondenza ad un nome espresso in caratteri è inserita nei due file
\conffile{/etc/passwd} e \conffile{/etc/group}.\footnote{in realtà negli
sistemi più moderni, come vedremo in sez.~\ref{sec:sys_user_group} queste
- informazioni possono essere mantenute, con l'uso del
- \itindex{Name~Service~Switch} \textit{Name Service Switch}, su varie
- tipologie di supporti, compresi server centralizzati come LDAP.} Questi
-identificativi sono l'\textit{user identifier}, detto in breve
-\textsl{user-ID}, ed indicato dall'acronimo \acr{uid}, e il \textit{group
- identifier}, detto in breve \textsl{group-ID}, ed identificato dall'acronimo
-\acr{gid}, torneremo in dettaglio su questo argomento in
+ informazioni possono essere mantenute, con l'uso del \textit{Name Service
+ Switch}, su varie tipologie di supporti, compresi server centralizzati
+ come LDAP.} Questi identificativi sono l'\textit{user identifier}, detto in
+breve \textsl{user-ID}, ed indicato dall'acronimo \ids{UID}, e il
+\textit{group identifier}, detto in breve \textsl{group-ID}, ed identificato
+dall'acronimo \ids{GID}, torneremo in dettaglio su questo argomento in
sez.~\ref{sec:proc_perms}. Il kernel conosce ed utilizza soltanto questi
valori numerici, i nomi ad essi associati sono interamente gestiti in
\textit{user space} con opportune funzioni di libreria, torneremo su questo
Infine in ogni sistema unix-like è presente uno speciale utente privilegiato,
il cosiddetto \textit{superuser}, il cui username è di norma \textit{root}, ed
-il cui \acr{uid} è zero. Esso identifica l'amministratore del sistema, che
+il cui \ids{UID} è zero. Esso identifica l'amministratore del sistema, che
deve essere in grado di fare qualunque operazione; per l'utente \textit{root}
infatti i meccanismi di controllo cui si è accennato in precedenza sono
-disattivati.\footnote{i controlli infatti vengono eseguiti da uno pseudocodice
+disattivati.\footnote{i controlli infatti vengono eseguiti da uno pseudo-codice
del tipo: ``\code{if (uid) \{ \textellipsis\ \}}''.}
+%Rimosse
+% \section{L'architettura della gestione dei file}
+% \label{sec:file_arch_func}
+
+\section{L'architettura di file e directory}
+\label{sec:intro_file_dir}
+
+Come accennato in sez.~\ref{sec:intro_base_concept} uno dei concetti
+fondamentali dell'architettura di un sistema Unix è il cosiddetto
+\textit{everything is a file} (\textsl{tutto è un file}), cioè il fatto che
+l'accesso ai vari dispositivi di input/output del computer viene effettuato
+attraverso un'interfaccia astratta che tratta le periferiche allo stesso modo
+dei normali file di dati.
+
+In questa sezione forniremo una descrizione a grandi linee dell'architettura
+della gestione dei file in Linux, partendo da una introduzione ai concetti di
+base, per poi illustrare la struttura dell'albero dei file ed il significato
+dei tipi di file, concludendo con una panoramica sulle caratteristiche
+principali delle due interfacce con cui i processi possono effettuare l'I/O su
+file.
+
+
+\subsection{Una panoramica generale}
+\label{sec:file_arch_overview}
+
+Per poter accedere ai file, il kernel deve mettere a disposizione dei
+programmi delle opportune \textit{system call} che consentano di leggere e
+scrivere il contenuto. Tutto ciò ha due aspetti: il primo è che il kernel, per
+il concetto dell'\textit{everything is a file}, deve fornire una interfaccia
+che consenta di operare sui file, sia che questi corrispondano ai normali file
+di dati, o ai cosiddetti \index{file!speciali} ``\textsl{file speciali}'',
+come \index{file!di~dispositivo} i file di dispositivo (o \textit{device
+ file}) che permettono di accedere alle periferiche o le fifo ed i socket che
+forniscono funzionalità di comunicazione fra processi.
+
+Il secondo aspetto è che per poter utilizzare dei normali file di dati il
+kernel deve provvedere ad organizzare e rendere accessibile in maniera
+opportuna l'informazione in essi contenuta memorizzandola sullo spazio grezzo
+disponibile sui dischi. Questo viene fatto strutturando l'informazione sul
+disco attraverso quello che si chiama un
+``\textit{filesystem}''. L'informazione così strutturata poi viene resa
+disponibile ai processi attraverso quello che viene chiamato il
+``\textsl{montaggio}'' del filesystem nell'albero dei file, dove il contenuto
+sarà accessibile nella forma ordinaria di file e directory.
+
+\itindbeg{Virtual~File~System}
+
+In Linux il concetto di \textit{everything is a file} è stato implementato
+attraverso il \textit{Virtual File System} (che da qui in poi abbrevieremo in
+VFS) che è uno strato intermedio che il kernel usa per accedere ai più
+svariati filesystem mantenendo la stessa interfaccia per i programmi in
+\textit{user space}.
+
+Il VFS fornisce cioè quel livello di astrazione che permette di collegare le
+operazioni interne del kernel per la manipolazione sui file con le
+\textit{system call} relative alle operazioni di I/O, e gestisce poi
+l'organizzazione di dette operazioni nei vari modi in cui i diversi filesystem
+le effettuano, permettendo la coesistenza di filesystem differenti all'interno
+dello stesso albero delle directory. Approfondiremo il funzionamento di
+interfaccia generica fornita dal VFS in sez.~\ref{sec:file_vfs_work}.
+
+In sostanza quello che accade è che quando un processo esegue una
+\textit{system call} che opera su un file, il kernel chiama sempre una
+funzione implementata nel VFS. La funzione eseguirà le manipolazioni sulle
+strutture generiche e utilizzerà poi la chiamata alle opportune funzioni del
+filesystem specifico a cui si fa riferimento. Saranno queste a chiamare le
+funzioni di più basso livello che eseguono le operazioni di I/O sul
+dispositivo fisico, secondo lo schema riportato in
+fig.~\ref{fig:file_VFS_scheme}.
+
+\begin{figure}[!htb]
+ \centering
+ \includegraphics[width=7cm]{img/vfs}
+ \caption{Schema delle operazioni del VFS.}
+ \label{fig:file_VFS_scheme}
+\end{figure}
+
+Questa interfaccia resta la stessa anche quando, invece che a dei normali
+file, si accede alle periferiche coi citati file di dispositivo, solo che in
+questo caso invece di usare il codice del filesystem che accede al disco, il
+\textit{Virtual File System} eseguirà direttamente il codice del kernel che
+permette di accedere alla periferica.
+
+\itindend{Virtual~File~System}
+
+Come accennato in precedenza una delle funzioni essenziali per il
+funzionamento dell'interfaccia dei file è quella che consente di montare un
+filesystem nell'albero dei file, e rendere così visibili i suoi contenuti. In
+un sistema unix-like infatti, a differenza di quanto avviene in altri sistemi
+operativi, tutti i file vengono mantenuti all'interno di un unico albero la
+cui radice (quella che viene chiamata \textit{root directory}) viene montata
+all'avvio direttamente dal kernel.
+
+Come accennato in sez.~\ref{sec:intro_kern_and_sys}) montare la radice è,
+insieme al lancio di \cmd{init},\footnote{l'operazione è ovviamente anche
+ preliminare al lancio di \cmd{init}, dato il kernel deve poter accedere al
+ file che contiene detto programma.} l'unica operazione che viene effettuata
+direttamente dal kernel in fase di avvio quando, completata la fase di
+inizializzazione, esso riceve dal bootloader l'indicazione di quale
+dispositivo contiene il filesystem da usare come punto di partenza e questo
+viene posto alla radice dell'albero dei file.
+
+Tutti gli ulteriori filesystem che possono essere disponibili su altri
+dispositivi dovranno a loro volta essere inseriti nell'albero, montandoli su
+altrettante directory del filesystem radice, su quelli che vengono chiamati
+\textit{mount point}. Questo comunque avverrà sempre in un secondo tempo, in
+genere a cura dei programmi eseguiti nella procedura di inizializzazione del
+sistema, grazie alle funzioni che tratteremo in
+sez.~\ref{sec:filesystem_mounting}.
+
+
+\subsection{La risoluzione del nome di file e directory}
+\label{sec:file_pathname}
+
+\itindbeg{pathname}
+
+Come illustrato sez.~\ref{sec:file_arch_overview} una delle caratteristiche
+distintive di un sistema unix-like è quella di avere un unico albero dei
+file. Un file deve essere identificato dall'utente usando quello che viene
+chiamato il suo \textit{pathname},\footnote{il manuale della \acr{glibc}
+ depreca questa nomenclatura, che genererebbe confusione poiché \textit{path}
+ indica anche un insieme di directory su cui effettuare una ricerca (come
+ quello in cui la shell cerca i comandi). Al suo posto viene proposto l'uso
+ di \textit{filename} e di componente per il nome del file all'interno della
+ directory. Non seguiremo questa scelta dato che l'uso della parola
+ \textit{pathname} è ormai così comune che mantenerne l'uso è senz'altro più
+ chiaro dell'alternativa proposta.} vale a dire tramite il
+``\textsl{percorso}'' (nome che talvolta viene usato come traduzione di
+\textit{pathname}) che si deve fare per accedere al file a partire da una
+certa ``\textit{directory}''.
+
+Una directory in realtà è anch'essa un file, nel senso che è anch'essa un
+oggetto di un filesystem, solo che è un file particolare che il kernel
+riconosce appositamente come tale per poterlo utilizzare come directory. Il
+suo scopo è quello di contenere una lista di nomi di file e le informazioni
+che associano ciascuno di questi nomi al relativo contenuto (torneremo su
+questo in sez.~\ref{sec:file_arch_func}).
+
+Dato che questi nomi possono corrispondere ad un qualunque altro oggetto del
+filesystem, compresa un'altra directory, si ottiene naturalmente
+un'organizzazione ad albero inserendo nomi di directory dentro altre
+directory. All'interno dello stesso albero si potranno poi inserire anche
+tutti gli altri oggetti previsti l'interfaccia del
+\itindex{Virtual~File~System} VFS (su cui torneremo in
+sez.~\ref{sec:file_file_types}), come le fifo, i collegamenti simbolici, i
+socket e gli stessi file di dispositivo.
+
+La convenzione usata nei sistemi unix-like per indicare i \textit{pathname}
+dei file è quella di usare il carattere ``\texttt{/}'' come separatore fra i
+nomi che indicano le directory che lo compongono. Dato che la directory radice
+sta in cima all'albero, essa viene indicata semplicemente con il
+\textit{pathname} \file{/}.
+
+\itindbeg{pathname~resolution}
+
+Un file può essere indicato rispetto ad una directory semplicemente
+specificandone il nome, il manuale della \acr{glibc} chiama i nomi contenuti
+nelle directory ``componenti'' (in inglese \textit{file name components}), noi
+li chiameremo più semplicemente \textsl{nomi} o \textsl{voci}, riservando la
+parola \textsl{componenti} ai nomi che, separati da una ``\texttt{/}'',
+costituiscono il \textit{pathname}. Questi poi dovranno corrispondere, perché
+il \textit{pathname} sia valido, a voci effettivamente presenti nelle
+directory, ma non è detto che un \textit{pathname} debba per forza risultare
+valido.
+
+Il procedimento con cui dato un \textit{pathname} si individua il file a cui
+esso fa riferimento, è chiamato \textsl{risoluzione del percorso}
+(\textit{filename resolution} o \textit{pathname resolution}). Lo stesso
+procedimento ci può anche dire che il \textit{pathname} usato non è valido.
+La risoluzione viene eseguita esaminando il \textit{pathname} da sinistra a
+destra e localizzando ogni componente dello stesso come nome in una directory
+a partire dalla directory iniziale, usando il carattere ``\texttt{/}'' come
+separatore per scendere dall'una all'altra. Nel caso si indichi un componente
+vuoto il costrutto ``\texttt{//}'' viene considerato equivalente a
+``\texttt{/}''.
+
+Ovviamente perché la risoluzione abbia successo occorre che i componenti
+intermedi esistano e siano effettivamente directory, e che il file o la
+directory indicata dall'ultimo componente esista. Inoltre i permessi relativi
+alle directory indicate nel \textit{pathname} (torneremo su questo
+sez.~\ref{sec:file_access_control}) dovranno consentire l'accesso all'intero
+\textit{pathname}.
+
+Se il \textit{pathname} comincia con il carattere ``\texttt{/}'' la ricerca
+parte dalla directory radice del processo. Questa, a meno di non avere
+eseguito una \func{chroot} (funzione su cui torneremo in
+sez.~\ref{sec:file_chroot}) è la stessa per tutti i processi ed equivale alla
+directory radice dell'albero dei file montata dal kernel all'avvio del
+sistema; in questo caso si parla di un \textsl{pathname assoluto}
+\itindsub{pathname}{assoluto}. Altrimenti la ricerca parte dalla
+\index{directory~di~lavoro} directory di lavoro corrente del processo (su cui
+torneremo in sez.~\ref{sec:file_work_dir}) ed il \textit{pathname} è detto
+\itindsub{pathname}{relativo} \textsl{pathname relativo}.
+
+Infine i nomi di directory ``\file{.}'' e ``\file{..}'' hanno un significato
+speciale e vengono inseriti in ogni directory quando questa viene creata (vedi
+sez.~\ref{sec:file_dir_creat_rem}). Il primo fa riferimento alla directory
+corrente e il secondo alla directory \textsl{genitrice} (o \textit{parent
+ directory}) cioè la directory che contiene il riferimento alla directory
+corrente.
+
+In questo modo con ``\file{..}'' si può usare un \itindsub{pathname}{relativo}
+\textit{pathname} relativo per indicare un file posto al di sopra della
+directory corrente, tornando all'indietro nell'albero dei file. Questa
+retromarcia però su fermerà una volta raggiunta la directory radice, perché
+non esistendo in questo caso una directory superiore, il nome ``\file{..}''
+farà riferimento alla radice stessa.
+
+\itindend{pathname}
+\itindend{pathname~resolution}
+
+
+\subsection{I tipi di file}
+\label{sec:file_file_types}
+
+Parlare dei tipi di file su Linux, come per qualunque sistema unix-like,
+significa anzitutto chiarire il proprio vocabolario e sottolineare le
+differenze che ci sono rispetto ad altri sistemi operativi.
+
+Come accennato in sez.~\ref{sec:file_arch_overview} su Linux l'uso del
+\itindex{Virtual~File~System} \textit{Virtual File System} consente di
+trattare come file oggetti molto diversi fra loro. Oltre ai normali file di
+dati abbiamo già accennato ad altri due di questi oggetti, i file di
+dispositivo e le directory, ma ne esistono altri. In genere quando si parla di
+tipo di file su Linux si fa riferimento a questi, di cui si riportato l'elenco
+completo in tab.~\ref{tab:file_file_types}.
+
+\begin{table}[htb]
+ \footnotesize
+ \centering
+ \begin{tabular}[c]{|l|l|p{6cm}|}
+ \hline
+ \multicolumn{2}{|c|}{\textbf{Tipo di file}} & \textbf{Descrizione} \\
+ \hline
+ \hline
+ \textit{regular file} & \textsl{file regolare} & Un file che contiene dei dati (l'accezione
+ normale di file).\\
+ \textit{directory} & \textsl{cartella o direttorio} & Un file che contiene una lista
+ di nomi associati a degli
+ \textit{inode} (vedi
+ sez.~\ref{sec:file_vfs_work}).\\
+ \textit{symbolic link} & \textsl{collegamento simbolico} & Un file che contiene un
+ riferimento ad un altro
+ file/directory.\\
+ \textit{char device} & \textsl{dispositivo a caratteri} & Un file \textsl{speciale}
+ che identifica una periferica
+ ad accesso a caratteri.\\
+ \textit{block device} & \textsl{dispositivo a blocchi} & Un file \textsl{speciale}
+ che identifica una periferica
+ ad accesso a blocchi.\\
+ \textit{fifo} & ``\textsl{coda}'' & Un file \textsl{speciale} che
+ identifica una linea di comunicazione
+ unidirezionale (vedi sez.~\ref{sec:ipc_named_pipe}).\\
+ \textit{socket} & ``\textsl{presa}''& Un file \textsl{speciale} che identifica una linea di
+ comunicazione bidirezionale (vedi
+ cap.~\ref{cha:socket_intro}).\\
+ \hline
+ \end{tabular}
+ \caption{Tipologia dei file definiti nel VFS}
+ \label{tab:file_file_types}
+\end{table}
+
+Si tenga ben presente che questa classificazione non ha nulla a che fare con
+una classificazione dei file in base al tipo loro del contenuto, dato che in
+tal caso si avrebbe a che fare sempre e solo con dei file di dati. E non ha
+niente a che fare neanche con le eventuali diverse modalità con cui si
+potrebbe accedere al contenuto dei file di dati. La classificazione di
+tab.~\ref{tab:file_file_types} riguarda il tipo di oggetti gestiti dal
+\itindex{Virtual~File~System} \textit{Virtual File System}, ed è da notare la
+presenza dei cosiddetti file ``\textsl{speciali}''.
+
+Alcuni di essi, come le \textit{fifo} (che tratteremo in
+sez.~\ref{sec:ipc_named_pipe}) ed i \textit{socket} (che tratteremo in
+cap.~\ref{cha:socket_intro}) non sono altro che dei riferimenti per utilizzare
+alcune funzionalità di comunicazione fornite dal kernel. Gli altri sono
+proprio quei \index{file!di~dispositivo} \textsl{file di dispositivo} che
+costituiscono una interfaccia diretta per leggere e scrivere sui dispositivi
+fisici. Anche se finora li abbiamo chiamati genericamente così, essi sono
+tradizionalmente suddivisi in due grandi categorie, \textsl{a blocchi} e
+\textsl{a caratteri} a seconda delle modalità in cui il dispositivo
+sottostante effettua le operazioni di I/O.
+
+I dispositivi a blocchi (ad esempio i dischi) sono quelli corrispondono a
+periferiche per le quali è richiesto che l'I/O venga effettuato per blocchi di
+dati di dimensioni fissate (nel caso dei dischi le dimensioni di un settore),
+mentre i dispositivi a caratteri sono quelli per cui l'I/O può essere
+effettuato senza nessuna particolare struttura, ed in generale anche un byte
+alla volta, da cui il nome.
+
+Una delle differenze principali con altri sistemi operativi come il VMS o
+Windows è che per Unix tutti i file di dati sono identici e contengono un
+flusso continuo di byte. Non esiste cioè differenza per come vengono visti dal
+sistema file di diverso contenuto o formato, come nel caso di quella fra file
+di testo e binari che c'è in Windows. Non c'è neanche una strutturazione a
+record per il cosiddetto ``\textsl{accesso diretto}'' come nel caso del
+VMS.\footnote{questo vale anche per i dispositivi a blocchi: la strutturazione
+ dell'I/O in blocchi di dimensione fissa avviene solo all'interno del kernel,
+ ed è completamente trasparente all'utente; inoltre talvolta si parla di
+ \textsl{accesso diretto} riferendosi alla capacità, che non ha niente a che
+ fare con tutto ciò, di effettuare, attraverso degli appositi
+ \index{file!di~dispositivo} file di dispositivo, operazioni di I/O
+ direttamente sui dischi senza passare attraverso un filesystem, il
+ cosiddetto \textit{raw access}, introdotto coi kernel della serie 2.4.x ma
+ ormai in sostanziale disuso.}
+
+Una differenza che attiene ai contenuti di un file però esiste, ed è relativa
+al formato dei file di testo. Nei sistemi unix-like la fine riga è codificata
+in maniera diversa da Windows o dal vecchio MacOS, in particolare il fine riga
+è il carattere \texttt{LF} (\verb|\n|) al posto del \texttt{CR} (\verb|\r|)
+del vecchio MacOS e del \texttt{CR LF} (\verb|\r\n|) di Windows. Questo può
+causare alcuni problemi qualora nei programmi si facciano assunzioni sul
+terminatore della riga e per questo esistono dei programmi come \cmd{unix2dos}
+e \cmd{dos2unix} che effettuano una conversione fra questi due formati di
+testo.
+
+Si ricordi comunque che un kernel unix-like non fornisce nessun supporto per
+la tipizzazione dei file di dati in base al loro contenuto e che non c'è
+nessun supporto per una qualche interpretazione delle estensioni (nel nome del
+file) da parte del kernel,\footnote{non è così ad esempio nel filesystem HFS
+ dei Mac, che supporta delle risorse associate ad ogni file, che specificano
+ fra l'altro il contenuto ed il programma da usare per leggerlo; in realtà
+ per alcuni filesystem esiste la possibilità di associare delle risorse ai
+ file con gli \textit{extended attributes} (vedi sez.~\ref{sec:file_xattr}),
+ ma è una caratteristica tutt'ora poco utilizzata, dato che non corrisponde
+ al modello classico dei file in un sistema Unix.} ogni classificazione di
+questo tipo avviene sempre in \textit{user-space}. Gli unici file di cui il
+kernel deve essere in grado di capire il contenuto sono i binari dei
+programmi, per i quali sono supportati solo alcuni formati, anche se oggi
+viene usato quasi esclusivamente l'ELF.\footnote{il nome è l'acronimo di
+ \textit{Executable and Linkable Format}, un formato per eseguibili binari
+ molto flessibile ed estendibile definito nel 1995 dal \textit{Tool Interface
+ Standard} che per le sue caratteristiche di non essere legato a nessun
+ tipo di processore o architettura è stato adottato da molti sistemi
+ unix-like e non solo.}
+
+Nonostante l'assenza di supporto da parte del kernel per la classificazione
+del contenuto dei file di dati, molti programmi adottano comunque delle
+convenzioni per i nomi dei file, ad esempio il codice C normalmente si mette
+in file con l'estensione \file{.c}. Inoltre una tecnica molto usata per
+classificare i contenuti da parte dei programmi è quella di utilizzare i primi
+byte del file per memorizzare un \itindex{magic~number} ``\textit{magic
+ number}''\footnote{il concetto è quello di un numero intero, solitamente fra
+ 2 e 10 byte, che identifichi il contenuto seguente, dato che questi sono
+ anche caratteri è comune trovare espresso tale numero con stringhe come
+ ``\texttt{\%PDF}'' per i PDF o ``\texttt{\#!}'' per gli script.} che ne
+classifichi il contenuto. Entrambe queste tecniche, per quanto usate ed
+accettate in maniera diffusa, restano solo delle convenzioni il cui rispetto è
+demandato alle applicazioni stesse.
+
+
+\subsection{Le due interfacce per l'accesso ai file}
+\label{sec:file_io_api}
+
+
+\itindbeg{file~descriptor}
+
+In Linux le interfacce di programmazione per l'I/O su file due. La prima è
+l'interfaccia nativa del sistema, quella che il manuale delle \textsl{glibc}
+chiama interfaccia dei ``\textit{file descriptor}'' (in italiano
+\textsl{descrittori di file}). Si tratta di un'interfaccia specifica dei
+sistemi unix-like che fornisce un accesso non bufferizzato.
+
+L'interfaccia è essenziale, l'accesso viene detto non bufferizzato in quanto
+la lettura e la scrittura vengono eseguite chiamando direttamente le
+\textit{system call} del kernel, anche se in realtà il kernel effettua al suo
+interno alcune bufferizzazioni per aumentare l'efficienza nell'accesso ai
+dispositivi. L'accesso viene gestito attraverso i \textit{file descriptor} che
+sono rappresentati da numeri interi (cioè semplici variabili di tipo
+\ctyp{int}). L'interfaccia è definita nell'\textit{header file}
+\headfile{unistd.h} e la tratteremo in dettaglio in
+sez.~\ref{sec:file_unix_interface}.
+
+\itindbeg{file~stream}
+
+La seconda interfaccia è quella che il manuale della \acr{glibc} chiama dei
+\textit{file stream} o più semplicemente degli \textit{stream}.\footnote{in
+ realtà una interfaccia con lo stesso nome è stata introdotta a livello di
+ kernel negli Unix derivati da \textit{System V}, come strato di astrazione
+ per file e socket; in Linux questa interfaccia, che comunque ha avuto poco
+ successo, non esiste, per cui facendo riferimento agli \textit{stream}
+ useremo il significato adottato dal manuale delle \acr{glibc}.} Essa
+fornisce funzioni più evolute e un accesso bufferizzato, controllato dalla
+implementazione fatta nella \acr{glibc}. Questa è l'interfaccia standard
+specificata dall'ANSI C e perciò si trova anche su tutti i sistemi non
+Unix. Gli \textit{stream} sono oggetti complessi e sono rappresentati da
+puntatori ad un opportuna struttura definita dalle librerie del C, ad essi si
+accede sempre in maniera indiretta utilizzando il tipo \code{FILE *}.
+L'interfaccia è definita nell'\textit{header file} \headfile{stdio.h} e la
+tratteremo in dettaglio in sez.~\ref{sec:files_std_interface}.
+
+Entrambe le interfacce possono essere usate per l'accesso ai file come agli
+altri oggetti del VFS, ma per poter accedere alle operazioni di controllo
+(descritte in sez.~\ref{sec:file_fcntl_ioctl}) su un qualunque tipo di oggetto
+del VFS occorre usare l'interfaccia standard di Unix con i file
+descriptor. Allo stesso modo devono essere usati i file descriptor se si vuole
+ricorrere a modalità speciali di I/O come il \itindex{file~locking}
+\textit{file locking} o l'I/O non-bloccante (vedi
+cap.~\ref{cha:file_advanced}).
+
+Gli \textit{stream} forniscono un'interfaccia di alto livello costruita sopra
+quella dei \textit{file descriptor}, che permette di poter scegliere tra
+diversi stili di bufferizzazione. Il maggior vantaggio degli \textit{stream}
+è che l'interfaccia per le operazioni di input/output è molto più ricca di
+quella dei \textit{file descriptor}, che forniscono solo funzioni elementari
+per la lettura/scrittura diretta di blocchi di byte. In particolare gli
+\textit{stream} dispongono di tutte le funzioni di formattazione per l'input e
+l'output adatte per manipolare anche i dati in forma di linee o singoli
+caratteri.
+
+In ogni caso, dato che gli \textit{stream} sono implementati sopra
+l'interfaccia standard di Unix, è sempre possibile estrarre il \textit{file
+ descriptor} da uno \textit{stream} ed eseguirvi sopra operazioni di basso
+livello, o associare in un secondo tempo uno \textit{stream} ad un
+\textit{file descriptor} per usare l'interfaccia più sofisticata.
+
+In generale, se non necessitano specificatamente le funzionalità di basso
+livello, è opportuno usare sempre gli \textit{stream} per la loro maggiore
+portabilità, essendo questi ultimi definiti nello standard ANSI C;
+l'interfaccia con i \textit{file descriptor} infatti segue solo lo standard
+POSIX.1 dei sistemi Unix, ed è pertanto di portabilità più limitata.
+
+\itindend{file~descriptor}
+\itindend{file~stream}
+
\section{Gli standard}
\label{sec:intro_standard}
\type{dev\_t} & Numero di dispositivo (vedi sez.~\ref{sec:file_mknod}).\\
\type{gid\_t} & Identificatore di un gruppo (vedi
sez.~\ref{sec:proc_access_id}).\\
- \type{ino\_t} & Numero di \index{inode} \textit{inode}.\\
+ \type{ino\_t} & Numero di \itindex{inode} \textit{inode}.\\
\type{key\_t} & Chiave per il System V IPC (vedi
sez.~\ref{sec:ipc_sysv_generic}).\\
\type{loff\_t} & Posizione corrente in un file.\\
\type{mode\_t} & Attributi di un file.\\
- \type{nlink\_t} & Contatore dei link su un file.\\
+ \type{nlink\_t} & Contatore dei collegamenti su un file.\\
\type{off\_t} & Posizione corrente in un file.\\
\type{pid\_t} & Identificatore di un processo (vedi
sez.~\ref{sec:proc_pid}).\\
sez.~\ref{sec:proc_access_id}).\\
\hline
\end{tabular}
- \caption{Elenco dei tipi primitivi, definiti in \file{sys/types.h}.}
+ \caption{Elenco dei tipi primitivi, definiti in \headfile{sys/types.h}.}
\label{tab:intro_primitive_types}
\end{table}
riferimento ai tipi elementari dello standard del linguaggio C, ma ad una
serie di \index{tipo!primitivo} \textsl{tipi primitivi} del sistema, riportati
in tab.~\ref{tab:intro_primitive_types}, e definiti nell'\textit{header file}
-\file{sys/types.h}, in modo da mantenere completamente indipendenti i tipi
+\headfile{sys/types.h}, in modo da mantenere completamente indipendenti i tipi
utilizzati dalle funzioni di sistema dai tipi elementari supportati dal
compilatore C.
Le funzionalità implementate sono principalmente il meccanismo di
intercomunicazione fra i processi e la memoria condivisa (il cosiddetto System
V IPC, che vedremo in sez.~\ref{sec:ipc_sysv}) le funzioni della famiglia
-\func{hsearch} e \func{drand48}, \func{fmtmsg} e svariate funzioni
+\funcm{hsearch} e \funcm{drand48}, \funcm{fmtmsg} e svariate funzioni
matematiche.
Benché BSD non sia mai stato uno standard formalizzato, l'implementazione
dello Unix dell'Università di Berkeley nella sua storia ha introdotto una
-serie di estensioni e interfacce di grandissima rilevanza, come i link
+serie di estensioni e interfacce di grandissima rilevanza, come i collegamenti
simbolici, la funzione \code{select} ed i socket di rete. Per questo motivo si
fa spesso riferimento esplicito alle interfacce presenti nelle varie versioni
dello Unix di Berkeley con una apposita sigla.
talvolta poi i riferimenti cambiano nome, per cui anche solo seguire le
denominazioni usate diventa particolarmente faticoso; una pagina dove si
possono recuperare varie (e di norma piuttosto intricate) informazioni è
-\href{http://www.pasc.org/standing/sd11.html}
-{\textsf{http://www.pasc.org/standing/sd11.html}}.
+\url{http://www.pasc.org/standing/sd11.html}.
\begin{table}[htb]
\footnotesize
\textbf{Standard} & \textbf{IEEE} & \textbf{ISO} & \textbf{Contenuto} \\
\hline
\hline
- POSIX.1 & 1003.1 & 9945-1& Interfacce di base \\
- POSIX.1a& 1003.1a& 9945-1& Estensioni a POSIX.1 \\
- POSIX.2 & 1003.2 & 9945-2& Comandi \\
- POSIX.3 & 2003 &TR13210& Metodi di test \\
- POSIX.4 & 1003.1b & --- & Estensioni real-time \\
- POSIX.4a& 1003.1c & --- & \itindex{thread} Thread \\
- POSIX.4b& 1003.1d &9945-1& Ulteriori estensioni real-time \\
- POSIX.5 & 1003.5 & 14519& Interfaccia per il linguaggio ADA \\
- POSIX.6 & 1003.2c,1e& 9945-2& Sicurezza \\
- POSIX.8 & 1003.1f& 9945-1& Accesso ai file via rete \\
- POSIX.9 & 1003.9 & --- & Interfaccia per il Fortran-77 \\
- POSIX.12& 1003.1g& 9945-1& Socket \\
+ POSIX.1 & 1003.1 & 9945-1& Interfacce di base. \\
+ POSIX.1a& 1003.1a& 9945-1& Estensioni a POSIX.1. \\
+ POSIX.2 & 1003.2 & 9945-2& Comandi. \\
+ POSIX.3 & 2003 &TR13210& Metodi di test. \\
+ POSIX.4 & 1003.1b & --- & Estensioni real-time. \\
+ POSIX.4a& 1003.1c & --- & \itindex{thread} Thread. \\
+ POSIX.4b& 1003.1d &9945-1& Ulteriori estensioni real-time. \\
+ POSIX.5 & 1003.5 & 14519& Interfaccia per il linguaggio ADA. \\
+ POSIX.6 & 1003.2c,1e& 9945-2& Sicurezza. \\
+ POSIX.8 & 1003.1f& 9945-1& Accesso ai file via rete. \\
+ POSIX.9 & 1003.9 & --- & Interfaccia per il Fortran-77. \\
+ POSIX.12& 1003.1g& 9945-1& Socket. \\
\hline
\end{tabular}
\caption{Elenco dei vari standard POSIX e relative denominazioni.}
Nelle versioni più recenti del kernel e delle librerie sono inoltre supportate
ulteriori funzionalità aggiunte dallo standard POSIX.1c per quanto riguarda i
-\itindex{thread} \textit{thread} (vedi cap.~\ref{cha:threads}), e dallo
-standard POSIX.1b per quanto riguarda i segnali e lo \itindex{scheduler}
-scheduling real-time (sez.~\ref{sec:sig_real_time} e
-sez.~\ref{sec:proc_real_time}), la misura del tempo, i meccanismi di
-intercomunicazione (sez.~\ref{sec:ipc_posix}) e l'I/O asincrono
-(sez.~\ref{sec:file_asyncronous_io}).
+\textit{thread} (vedi cap.~\ref{cha:threads}), e dallo standard POSIX.1b per
+quanto riguarda i segnali e lo scheduling real-time
+(sez.~\ref{sec:sig_real_time} e sez.~\ref{sec:proc_real_time}), la misura del
+tempo, i meccanismi di intercomunicazione (sez.~\ref{sec:ipc_posix}) e l'I/O
+asincrono (sez.~\ref{sec:file_asyncronous_io}).
Lo standard principale resta comunque POSIX.1, che continua ad evolversi; la
versione più nota, cui gran parte delle implementazioni fanno riferimento, e
\macro{\_GNU\_SOURCE}) è stata a sua volta attivata, nel qual caso queste
hanno la precedenza. Se però si definisce \macro{\_BSD\_SOURCE} dopo aver
definito una di queste macro, l'effetto sarà quello di dare la precedenza
- alle funzioni in forma BSD.
+ alle funzioni in forma BSD. Questa macro è stata deprecata a partire dalle
+ \acr{glibc} 2.20, essendo ricompresa in \macro{\_DEFAULT\_SOURCE} che è
+ definita di default.
\item[\macro{\_SVID\_SOURCE}] definendo questa macro si rendono disponibili le
funzionalità derivate da SVID. Esse comprendono anche quelle definite negli
standard ISO C, POSIX.1, POSIX.2, e X/Open (XPG$n$) illustrati in
- precedenza.
+ precedenza. Questa macro è stata deprecata a partire dalle \acr{glibc} 2.20,
+ essendo ricompresa in \macro{\_DEFAULT\_SOURCE} che è definita di default.
+
+\item[\macro{\_DEFAULT\_SOURCE}] questa macro abilita le definizioni
+ considerate il \textit{default}, comprese quelle richieste dalla standard
+ POSIX.1-2008, ed è sostanzialente equivalente a \macro{\_SVID\_SOURCE}
+ \macro{\_BSD\_SOURCE}] e \macro{\_POSIX\_C\_SOURCE}. Essendo predefinita non
+ è necessario usarla a meno di non aver richiesto delle definizioni più
+ restrittive sia con altre macro che con i flag del compilatore, nel qual
+ caso abilita le funzioni che altrimenti sarebbero disabilitate. Questa macro
+ è stata introdotta a partire dalle \acr{glibc} 2.19 e consente di deprecare
+ \macro{\_SVID\_SOURCE} e \macro{\_BSD\_SOURCE}].
\item[\macro{\_XOPEN\_SOURCE}] definendo questa macro si rendono disponibili
le funzionalità descritte nella \textit{X/Open Portability Guide}. Anche
viene tuttora riconosciuta come equivalente di \macro{\_ISOC99\_SOURCE} per
compatibilità.
+\item[\macro{\_ISOC11\_SOURCE}] definendo questa macro si rendono disponibili
+ le funzionalità previste per la revisione delle librerie standard del C
+ introdotte con lo standard ISO C11, e abilita anche quelle previste dagli
+ standard C99 e C95. La macro è definita a partire dalla versione 2.16 della
+ \acr{glibc}.
+
\item[\macro{\_GNU\_SOURCE}] definendo questa macro si rendono disponibili
tutte le funzionalità disponibili nei vari standard oltre a varie estensioni
specifiche presenti solo nella \acr{glibc} ed in Linux. Gli standard coperti
presente negli standard con i file di grandi dimensioni, ed in particolare
definire le due funzioni \func{fseeko} e \func{ftello} che al contrario
delle corrispettive \func{fseek} e \func{ftell} usano il tipo di dato
- specifico \ctyp{off\_t} (vedi sez.~\ref{sec:file_fseek}).
+ specifico \type{off\_t} (vedi sez.~\ref{sec:file_io}).
\item[\macro{\_LARGEFILE64\_SOURCE}] definendo questa macro si rendono
disponibili le funzioni di una interfaccia alternativa al supporto di valori
a 64 bit nelle funzioni di gestione dei file (non supportati in certi
sistemi), caratterizzate dal suffisso \texttt{64} aggiunto ai vari nomi di
- tipi di dato e funzioni (come \ctyp{off64\_t} al posto di \ctyp{off\_t} o
- \func{lseek64} al posto di \func{lseek}).
+ tipi di dato e funzioni (come \type{off64\_t} al posto di \type{off\_t} o
+ \funcm{lseek64} al posto di \func{lseek}).
Le funzioni di questa interfaccia alternativa sono state proposte come una
estensione ad uso di transizione per le \textit{Single UNIX Specification},
\item[\macro{\_ATFILE\_SOURCE}] definendo questa macro si rendono disponibili
le estensioni delle funzioni di creazione, accesso e modifica di file e
- directory che risolvono i problemi di sicurezza insiti nell'uso di pathname
- relativi con programmi \itindex{thread} \textit{multi-thread} illustrate in
- sez.~\ref{sec:file_openat}.
+ directory che risolvono i problemi di sicurezza insiti nell'uso di
+ \textit{pathname} relativi con programmi \itindex{thread}
+ \textit{multi-thread} illustrate in sez.~\ref{sec:file_openat}.
\item[\macro{\_REENTRANT}] definendo questa macro, o la equivalente
\macro{\_THREAD\_SAFE} (fornita per compatibilità) si rendono disponibili le
Le funzioni di libreria che vengono messe sotto controllo quando questa
funzionalità viene attivata sono, al momento della stesura di queste note,
- le seguenti: \func{memcpy}, \func{mempcpy}, \func{memmove}, \func{memset},
- \func{stpcpy}, \func{strcpy}, \func{strncpy}, \func{strcat}, \func{strncat},
- \func{sprintf}, \func{snprintf}, \func{vsprintf}, \func{vsnprintf}, e
- \func{gets}.
+ le seguenti: \funcm{memcpy}, \funcm{mempcpy}, \funcm{memmove},
+ \funcm{memset}, \funcm{stpcpy}, \funcm{strcpy}, \funcm{strncpy},
+ \funcm{strcat}, \funcm{strncat}, \func{sprintf}, \func{snprintf},
+ \func{vsprintf}, \func{vsnprintf}, e \func{gets}.
La macro prevede due valori, con \texttt{1} vengono eseguiti dei controlli
di base che non cambiano il comportamento dei programmi se si richiede una
% LocalWords: assert ctype dirent errno fcntl limits malloc setjmp signal utmp
% LocalWords: stdarg stdio stdlib string times unistd library int short caddr
% LocalWords: address clock dev ino inode key IPC loff nlink off pid rlim size
-% LocalWords: sigset ssize ptrdiff sys IEEE Richard Portable of TR
+% LocalWords: sigset ssize ptrdiff sys IEEE Richard Portable of TR filesystem
% LocalWords: Operating Interface dell'IEEE Electrical and Electronics thread
% LocalWords: Engeneers Socket NT matching regular expression scheduling l'I
% LocalWords: XPG Portability Issue Application Programmable XTI Transport AT
% LocalWords: drand fmtmsg define SOURCE lbsd compat XOPEN version ISOC Large
% LocalWords: LARGEFILE Support LFS dell' black rectangle node fill cpu draw
% LocalWords: ellipse mem anchor west proc SysV SV Definition SCO Austin XSI
-% LocalWords: Technical TC SUS Opengroup features STRICT std ATFILE fseeko
+% LocalWords: Technical TC SUS Opengroup features STRICT std ATFILE fseeko VFS
% LocalWords: ftello fseek ftell lseek FORTIFY REENTRANT SAFE overflow memcpy
% LocalWords: mempcpy memmove memset stpcpy strcpy strncpy strcat strncat gets
% LocalWords: sprintf snprintf vsprintf vsnprintf syscall number calendar BITS
-% LocalWords: pathname Google Android standards
+% LocalWords: pathname Google Android standards device Virtual bootloader path
+% LocalWords: filename fifo name components resolution chroot parent symbolic
+% LocalWords: char block VMS raw access MacOS LF CR dos HFS Mac attributes
+% LocalWords: Executable Linkable Format Tool magic descriptor stream locking
+% LocalWords: process
%%% Local Variables:
%%% mode: latex