Roba di ieri, riscritte meglio (spero) alcune parti
authorSimone Piccardi <piccardi@gnulinux.it>
Fri, 6 Apr 2001 15:42:53 +0000 (15:42 +0000)
committerSimone Piccardi <piccardi@gnulinux.it>
Fri, 6 Apr 2001 15:42:53 +0000 (15:42 +0000)
files.tex
intro.tex
main.tex

index a9f253b42f83c52eb13068c24339401fcfa4cf13..e3c994d5b96e735ac94acd5f21a453256e04607a 100644 (file)
--- a/files.tex
+++ b/files.tex
@@ -1,44 +1,55 @@
-\chapter{I files}
+\chapter{I files: introduzione}
 \label{cha:files}
-
 Uno dei concetti fondamentali del design di unix è il cosiddetto
-\textit{everything is a file}, cioè il fatto che l'accesso alle periferiche
-viene gestito attraverso un'interfaccia astratta che tratta nello stesso modo
-sia i normali file di dati che le periferiche. Si può accedere cioè a queste
-ultime (con l'eccezione delle interfacce di rete) attraverso i cosiddetti file
-di dispositivo (i \textit{device files}) che permettono ai programmi di
-interfacciarsi alle varie periferiche come la seriale, la parallela, la
-console, e gli stessi dischi.
-
-\section{Concetti generali sui files}
+\textit{everything is a file}, cioè il fatto che l'accesso ai vari dispositivi
+di I/O del computer viene effettuato attraverso un'interfaccia astratta che
+tratta le periferiche allo stesso modo degli usuali file di dati.
+
+Si può accedere cioè a qualunque periferica del computer, dalla seriale, alla
+parallela, alla console, e agli stessi dischi, (unica eccezione le interfacce
+di rete, che che non rientrano bene nell'astrazione) attraverso i cosiddetti
+file di dispositivo (i \textit{device files}). Questi sono dei file speciali
+agendo sui quali i programmi possono leggere, scrivere e compiere operazioni
+sulle perferiche, usando le stesse funzioni che si usano per i normali file di
+dati.
+
+\section{Concetti generali riguardanti i files}
 \label{sec:file_gen}
 
-Per poter accedere ai singoli file su disco è necessario l'uso di un
-\textit{filesystem}, cioè di un'interfaccia del kernel che permetta di
-strutturare l'informazione tenuta sullo spazio grezzo disponibile sui dischi
-in files e directory. Sarà quest'ultimo a gestire l'accesso ai dati
-memorizzati all'interno del disco stesso, e l'uso delle normali directory e
-files.
+Visto il ruolo fondamentale che i files vengono ad assumere in un sistema
+unix, è anzitutto opportuno fornire un'introduzione dettagliata su come essi
+vengono trattati dal sistema. In particolare occorre tenere presente dov'è che
+si situa il limite fondamentale fra kernel space e user space che tracciavamo
+al Cap.~\ref{cha:intro_unix}.
+
+Partiamo allora da come viene strutturata nel sistema la disposizione dei
+file: per potervi accedere il kernel usa una apposita interfaccia che permetta
+di strutturare l'informazione tenuta sullo spazio grezzo disponibile sui
+dischi, cioè quello che si chiama un \textit{filesystem}. 
+
+Sarà attraverso quest'ultimo che il kernel andrà a gestire l'accesso ai dati
+memorizzati all'interno del disco stesso, strutturando l'informazione in files
+e directory.  Per poter accedere ai file contenuti in un disco occorrerà
+perciò attivare il filesystem, questo viene fatto \textsl{montando} il disco
+(o la partizione del disco).
 
 %In generale un filesystem piazzerà opportunamente sul disco dei blocchi di
 %informazioni riservate che tengono conto degli inodes allocati, di quelli
 %liberi, e delle posizioni fisiche su disco dei dati contenuti nei files, per
 
-Per poter accedere ai file contenuti in un disco occorrerà poi attivare il
-filesystem \textit{montando} il disco (o la partizione del disco). 
-
-In unix, a differenza di quanto avviene in altri sistemi operativi, tutti i
+In Unix, a differenza di quanto avviene in altri sistemi operativi, tutti i
 file vengono tenuti all'interno di un unico albero la cui radice (la directory
 di \textit{root}) viene montata all'avvio. Pertanto un file viene identificato
-dall'utente usando il suo \textit{pathname}, cioè il percorso completo che si
-deve fare a partire dalla radice, per accedere al file.
+dall'utente usando quello che viene chiamato \textit{pathname}, cioè il
+percorso completo che si deve fare a partire dalla radice, per accedere al
+file.
 
 Dopo la fase di inizializzazione il kernel riceve dal boot loader
 l'indicazione di quale dispositivo contiene il filesystem da usare come punto
 di partenza e questo viene montato come radice dell'albero (cioè nella
 directory \texttt{/}); tutti gli ulteriori dischi devono poi essere inseriti
-nell'albero utilizzando opportune subdirectory (in genere sotto
-\texttt{/mnt}) .
+nell'albero utilizzando opportune subdirectory.
 
 Alcuni filesystem speciali (come \texttt{/proc} che contiene un'interfaccia ad
 alcune strutture interne del kernel) sono generati automaticamente dal kernel
@@ -71,19 +82,19 @@ coesistenza di diversi filesystem all'interno dello stesso kernel.
 
 La funzione più importante implementata dal VFS è la system call \texttt{open}
 che permette di aprire un file. Dato un pathname viene eseguita una ricerca
-dentro la \textit{directory entry cache} (la \textit{dcache}) una tabella di
-hash che contiene tutte le \textit{directory entry} (in breve \textit{dentry})
-che permette di associare in maniera rapida ed efficiente il pathname a una
-specifica dentry.
+dentro la \textit{directory entry cache} (in breve \textit{dcache}) che è
+una tabella di hash che contiene tutte le \textit{directory entry} (in breve
+\textit{dentry}) che permette di associare in maniera rapida ed efficiente il
+pathname a una specifica dentry.
 
 Una singola dentry contiene in genere il puntatore ad un \textit{inode};
 quest'ultimo è la struttura base che sta sul disco e che identifica un singolo
-oggetto del VFS che può essere un file, una directory, una FIFO, un file di
-dispositivo, o una qualsiasi altra cosa che possa essere rappresentata dal
-VFS (sui tipi di files possibili torneremo in seguito).
+oggetto del VFS sia esso un file ordinario, una directory, una FIFO, un file
+di dispositivo, o una qualsiasi altra cosa che possa essere rappresentata dal
+VFS (sui tipi di ``files'' possibili torneremo in seguito).
 
 Le dentries ``vivono'' in memoria e non vengono mai salvate su disco, vengono
-usate per motivi di velocità, gli inodes invece vivono su disco e vengono
+usate per motivi di velocità, gli inodes invece stanno su disco e vengono
 copiati in memoria quando serve, ed ogni cambiamento viene copiato
 all'indietro sul disco, gli inodes che stanno in memoria sono inodes del VFS
 ed è ad essi che puntano le singole dentry.
@@ -111,11 +122,6 @@ user space possono accedere alle operazioni attraverso detti metodi, che
 saranno diversi a seconda del tipo di file (o dispositivo) aperto. Un elenco
 delle operazioni disponibili è riportato in \ntab.
 
-% La struttura file viene poi inserita nella tavola dei file
-% , non
-% tutte le operazioni possibili sono definite per tutti i dispositivi; un elenco
-% delle operazioni definite in linux è riportato in \ntab.
-
 \begin{table}[htb]
   \centering
   \begin{tabular}[c]{c p{7cm}}
@@ -149,32 +155,33 @@ utilizzare la opportuna routine dichiarata in \verb|f_ops| appropriata al tipo
 di file in questione. 
 
 Così sarà possibile scrivere sulla porta seriale come su un file di dati
-normale; ovviamente certe operazioni (nel caso la \textit{seek}) non saranno
-disponibili, però con questo sistema l'utilizzo di diversi filesystem è
-immediato e (relativamente) trasparente per l'utente ed il programmatore.
+normale; ovviamente certe operazioni (nel caso della seriale ad esempio la
+\textit{seek}) non saranno disponibili, però con questo sistema l'utilizzo di
+diversi filesystem (come quelli usati da Windows o MacOs) è immediato e
+(relativamente) trasparente per l'utente ed il programmatore.
 
 \subsection{Proprietari e permessi}
 \label{sec:file_perms}
 
-In unix è implementata da qualunque filesystem standard una forma elementare
+In Unix è implementata da qualunque filesystem standard una forma elementare
 (ma adatta alla maggior parte delle esigenze) di controllo di accesso ai
 files. Torneremo sull'argomento in dettaglio più avanti, qui ci limitiamo ad
 una introduzione dei concetti essenziali.
 
-Si tenga conto poi che quanto diremo è vero solo per filesystem di tipo unix,
+Si tenga conto poi che quanto diremo è vero solo per filesystem di tipo Unix,
 e non è detto che sia applicabile (ed infatti non è vero per il filesystem di
-windows) a un filesystem qualunque. Esistono inoltre estensioni che permettono
+Windows) a un filesystem qualunque. Esistono inoltre estensioni che permettono
 di implementare le ACL (\textit{Access Control List}) che sono un meccanismo
 di controllo di accesso molto più sofisticato.
 
-Ad ogni file unix associa sempre l'utente che ne è proprietario (il cosiddetto
+Ad ogni file Unix associa sempre l'utente che ne è proprietario (il cosiddetto
 \textit{owner}) e il gruppo di appartenenza, secondo il meccanismo degli uid e
 gid spiegato in \ref{sec:intro_usergroup}, e un insieme di permessi che sono
 divisi in tre classi, e cioè attribuiti rispettivamente al proprietario, a
 qualunque utente faccia parte del gruppo cui appartiene il file, e a tutti gli
 altri utenti.
 
-I permessi sono espressi da un insieme di 12 bit, di questi i nove meno
+I permessi sono espressi da un insieme di 12 bit: di questi i nove meno
 significativi sono usati a gruppi di tre per indicare i permessi base di
 lettura, scrittura ed esecuzione (indicati rispettivamente con le lettere
 \textit{w}, \textit{r} \textit{x}) applicabili rispettivamente al
@@ -220,7 +227,7 @@ dei vari tipi di file 
       \textit{fifo} & \textsl{tubo} &
       un file speciale che identifica una linea di comunicazione software
       (unidirezionale) \\
-      \textit{socket} & \textsl{presa} &
+      \textit{socket} & \textsl{manicotto} &
       un file speciale che identifica una linea di comunicazione software
       (bidirezionale) \\
     \hline
@@ -233,26 +240,27 @@ dei vari tipi di file 
 Tutto ciò non ha ovviamente nulla a che fare con la classificazione sui tipi
 di file (in questo caso file di dati) in base al loro contenuto, o tipo di
 accesso.  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
+VMS o Windows) è che per Unix tutti i file di dati sono identici e contengono
 un flusso continuo di bytes; 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) né c'è una strutturazione a record
 per il cosiddetto ``accesso diretto'' come nel caso del VMS.
 
-Una seconda differenza è nel formato dei file ascii; in unix la fine riga è
-codificata in maniera diversa da windows o macintosh, in particolare il fine
-riga è il carattere \texttt{LF} al posto del \texttt{CR} del mac e del
-\texttt{CR LF} di windows. Questo può causare alcuni problemi qualora si
-facciano assunzioni sul terminatore della riga.
+Una seconda differenza è nel formato dei file ascii; in Unix la fine riga è
+codificata in maniera diversa da Windows o MacIntosh, in particolare il fine
+riga è il carattere \texttt{LF} (o \verb|\n|) al posto del \texttt{CR}
+(\verb|\r|) del mac e del \texttt{CR LF} di windows. Questo può causare alcuni
+problemi qualora si facciano assunzioni sul terminatore della riga.
 
 
-\section{Una panoramica sull'I/O sui file}
+\section{Una panoramica sull'uso dei file}
 \label{sec:file_io_base}
 
 Per poter accedere al contenuto dei file occorre anzitutto aprirlo. Questo
 crea un canale di comunicazione che permette di eseguire una serie di
 operazioni. Una volta terminate le operazioni, il file dovrà essere chiuso, e
-questo chiuderà il canale di comunicazione impedendo ogni ulteriore operazione.
+questo chiuderà il canale di comunicazione impedendo ogni ulteriore
+operazione.
 
 
 \subsection{Le due interfacce ai file}
@@ -262,14 +270,14 @@ In unix le modalit
 programmazione sono due, basate su due diversi meccanismi di connessione. 
 
 La prima è quella dei cosiddetti \textit{file descriptor} (descrittore di
-file), che è specifica di unix e che provvede un accesso diretto a basso
+file), che è specifica di Unix e che provvede un accesso diretto a basso
 livello non bufferizzato, con un'interfaccia primitiva ed essenziale; i file
 descriptors sono rappresentati da numeri interi (cioè semplici variabili di
 tipo \texttt{int}). L'interfaccia è definita nell'header \texttt{unistd.h}.
 
 La seconda è quella degli \textit{stream}, che provvede un'interfaccia più
 evoluta e un accesso bufferizzato. Questa è anche l'interfaccia standard usata
-dal linguaggio C e perciò si trova anche su tutti i sistemi non unix. Gli
+dal linguaggio C e perciò si trova anche su tutti i sistemi non Unix. Gli
 stream sono oggetti complessi e sono rappresentati da puntatori ad un
 opportuna struttura definita dalle librerie del C, si accede ad essi sempre in
 maniera indiretta utilizzando il tipo \texttt{FILE *}. L'interfaccia è
@@ -289,8 +297,8 @@ l'eccezione di poter scegliere tre diversi stili di bufferizzazione.  Il
 maggior vantaggio degli stream è che l'interfaccia per le operazioni di
 input/output è enormemente più ricca di quella dei file descriptor, che
 provvedono solo funzioni elementari per la lettura/scrittura diretta di
-blocchi di bytes.  In particolare dispongono di tutte le funzioni di
-formattazione per l'input e l'output adatte per manipolare anche i dati in
+blocchi di bytes.  In particolare gli 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 stream sono implementati sopra l'interfaccia a
@@ -308,7 +316,7 @@ pertanto di portabilit
 \label{sec:files_spec_unix}
 
 Essendo un sistema multitasking e multiutente esistono alcune caratteristiche
-specifiche di unix che devono essere tenute in conto nell'accesso ai file. È
+specifiche di Unix che devono essere tenute in conto nell'accesso ai file. È
 infatti normale che più processi o programmi possano accedere
 contemporaneamente allo stesso file e devono poter eseguire le loro operazioni
 indipendentemente da quello che fanno gli altri processi.
@@ -334,18 +342,18 @@ ogni processo avr
 influenzata da quello che altri processi possono fare. Anzi, aprire un file
 significa appunto creare ed inizializzare una tale struttura, per cui se si
 apre due volte lo stesso file all'interno dello stesso processo, si otterrano
-due file descriptor o due stream che avranno ancora un posizione corrente nel
+due file descriptor o due stream che avranno ancora una posizione corrente nel
 file assolutamente indipendente.
 
 Si tenga conto inoltre che un'altro dei dati contenuti nella struttura di
 accesso è un riferimento all'inode del file, pertanto anche se il file viene
-cancellato da un altro processo, sarà sempre possibile mantenere l'accesso,
-e lo spazio su disco non verrà rilasciato fintanto che il file non sarà chiuso
-e l'ultimo riferimento cancellato. È pertanto possibile (e pratica comune)
-aprire un file provvisorio per cancellarlo immediatamente dopo; in questo modo
-all'uscita del programma il file scomparirà definitivamente dal disco, ma il
-file ed il suo contenuto saranno disponibili per tutto il tempo in cui il
-processo è attivo.
+cancellato da un altro processo, sarà sempre possibile mantenere l'accesso ai
+dati, e lo spazio su disco non verrà rilasciato fintanto che il file non sarà
+chiuso e l'ultimo riferimento cancellato. È pertanto possibile (e pratica
+comune) aprire un file provvisorio per cancellarlo immediatamente dopo; in
+questo modo all'uscita del programma il file scomparirà definitivamente dal
+disco, ma il file ed il suo contenuto saranno disponibili per tutto il tempo
+in cui il processo è attivo.
 
 
 \subsection{L'accesso ai files: nomi e directory}
@@ -365,12 +373,12 @@ semplicemente specificando il nome da essa contenuto. Una directory contiene
 semplicemente un elenco di questi componenti, che possono corrispondere a un
 qualunque oggetto del filesystem, compresa un'altra directory.
 
-Un nome di file è composto da una serie di componenti separati da una
+Un nome di file è composto da una serie di \textsl{componenti} separati da una
 \texttt{/} (in linux più \texttt{/} consecutive sono considerate equivalenti
 ad una sola). Il nome completo di un file viene usualmente chiamato
-\textit{pathname}, anche se questo può generare confusione, dato che con
-\textit{path} si indica anche un insieme di directory su cui effettuare una
-ricerca (ad esempio quello in cui si cercano i comandi).
+\textit{filename} o \textit{pathname}, anche se quest'ultimo può generare
+confusione, dato che con \textit{path} si indica anche un insieme di directory
+su cui effettuare una ricerca (ad esempio quello in cui si cercano i comandi).
 
 Il processo con cui si associa ad un pathname uno specifico file (cioè si
 identifica l'inode a cui fare riferimento) è chiamato risoluzione del nome
@@ -395,11 +403,11 @@ il secondo alla directory \textsl{genitore} (\textit{parent directory}) cio
 la directory che contiene il riferimento alla directory corrente; nel caso
 questa sia la directory radice allora il riferimento è a se stessa.
 
-Infine si ricordi che in unix non esistono i tipi di file e che non c'è nessun
+Infine si ricordi che in Unix non esistono i tipi di file e che non c'è nessun
 supporto per le estensioni come parte del filesystem. Ciò non ostante molti
 programmi adottano delle convenzioni per i nomi dei file, ad esempio il codice
-C normalmente si mette in file con l'estensione .c, ma questa è solo una
-convenzione.
+C normalmente si mette in file con l'estensione .c, ma questa è, appunto, solo
+una convenzione.
 
 
 \section{L'interfaccia al filesystem}
@@ -602,8 +610,8 @@ nell'header file \texttt{unistd.h}.
 \begin{itemize}
 \item \texttt{int link(const char * oldname, const char * newname)}
   
-  Crea un nuovo link al file  indicato da \texttt{oldname} dandogli nome
-  \texttt{newname}.
+  Crea un nuovo link diretto al file indicato da \texttt{oldname} dandogli
+  nome \texttt{newname}.
   
   La funzione restituisce zero in caso di successo e -1 per un errore, in caso
   di errore. La variabile \texttt{errno} viene settata secondo i codici di
@@ -611,6 +619,10 @@ nell'header file \texttt{unistd.h}.
   \ref{sec:file_err_acc}) ai quali si aggiungono i seguenti:
 
   \begin{itemize}
+  \item \texttt{EXDEV} \texttt{oldname} e \texttt{newname} non sono sullo
+    stesso filesystem.
+  \item \texttt{EPERM} il filesystem che contiene \texttt{oldname} e
+    \texttt{newname} non supporta i link diretti.
   \item \texttt{EACCESS} 
     Non c'è il permesso di scrittura per la directory in cui si vuole creare
     il nuovo link.
@@ -620,13 +632,39 @@ nell'header file \texttt{unistd.h}.
     numero massimo è specificato dalla variabile \texttt{LINK\_MAX}, vedi
     \ref{sec:sys_limits}.
   \item \texttt{ENOSPC} La directory in cui si vuole creare il link è piena e
-    non può essere .
+    non può essere ampliata.
   \item \texttt{EROFS} La directory su cui si vuole inserire il nuovo link è
     su un filesystem montato readonly.
   \end{itemize}
 \end{itemize}
 
 
+\begin{itemize}
+\item \texttt{int symlink(const char * oldname, const char * newname)}
+  
+  Crea un nuovo link simbolico al file indicato da \texttt{oldname} dandogli
+  nome \texttt{newname}.
+  
+  La funzione restituisce zero in caso di successo e -1 per un errore, in caso
+  di errore. La variabile \texttt{errno} viene settata secondo i codici di
+  errore standard di accesso ai files (trattati in dettaglio in
+  \ref{sec:file_err_acc}) ai quali si aggiungono i seguenti:
+
+  \begin{itemize}
+  \item \texttt{EEXIST} Un file (o una directory) con quel nome esiste di
+    già.
+  \item \texttt{EROFS} La directory su cui si vuole inserire il nuovo link è
+    su un filesystem montato readonly.
+  \item \texttt{ENOSPC} La directory o il filesystem in cui si vuole creare il
+    link è piena e non c'è ulteriore spazio disponibile.
+  \item \texttt{ELOOP} Ci sono troppi link simbolici nella risoluzione di
+    \texttt{oldname} o di \texttt{newname}.
+  \end{itemize}
+\end{itemize}
+
+
+
+
 \section{L'input/output di basso livello}
 \label{sec:file_lowlev_io}
 %
index bc81fb739e9469394c43497c2e3af0bf4e3e51b7..bbee690e8fb28a886e491fe8128b71e360fbefe5 100644 (file)
--- a/intro.tex
+++ b/intro.tex
@@ -1,4 +1,5 @@
 \chapter{Introduzione}
+\label{cha:intro_unix}
 
 In questo primo capitolo sarà fatta un'introduzione ai contetti generali su
 cui è basato un sistema di tipo unix, per fornire una base di comprensione
@@ -200,3 +201,5 @@ qualunque operazione; pertanto per l'utente root i meccanismi di controllo
 descritti in precedenza sono disattivati.
 
 
+
+
index 569f7086acebb9424631e2086f6f237199fdbfd5..9fe6813eb577c354cbfe80032015c359392fe774 100644 (file)
--- a/main.tex
+++ b/main.tex
@@ -28,8 +28,6 @@
 
 %\includeonly{macro,pref,intro,fdl}
 
-
-
 \title{Guida alla Programmazione in Linux.}
 
 \author{Simone Piccardi}