Aggiunte mknod e mkfifo, e fatta una passata di ispell
[gapil.git] / filedir.tex
index b09d7609c60de190299697755e247fd2e3da6891..df14491c79b92f85f7a1025070d5795a2c334832 100644 (file)
@@ -514,59 +514,73 @@ un caso a parte, che vedremo in \secref{cha:socket_intro}).
 
 La manipolazione delle caratteristiche di questi filee e la loro cancellazione
 può essere effettuata con le stesse funzioni che operano sui file normali; ma
-quando li si devono creare sono necessarie delle funzioni apposite. 
-
+quando li si devono creare sono necessarie delle funzioni apposite. La prima
+di queste funzioni è \func{mknod}, il suo prototipo è:
 \begin{functions}
   \headdecl{sys/types.h}
   \headdecl{sys/stat.h}
   \headdecl{fnctl.h}
   \headdecl{unistd.h}
-  \funcdecl{int mknod(const char *pathname, mode\_t mode, dev\_t dev)} 
+  \funcdecl{int mknod(const char *pathname, mode\_t mode, dev\_t dev)} Crea un
+  inode, si usa per creare i file speciali.
   
   \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[\macro{EPERM}] Il filesystem non supporta la cancellazione di
-    directory, oppure la directory che contiene \var{dirname} ha lo sticky bit
-    settato e l'\textit{effective user id} del processo non corrisponde al
-    proprietario della directory. 
-  \item[\macro{EACCESS}] 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
-    \var{dirname}.
-  \item[\macro{EBUSY}] La directory specificata è la directory di lavoro o la
-    radice di qualche processo.
-  \item[\macro{ENOTEMPTY}] La directory non è vuota.
+  \item[\macro{EPERM}] Non si hanno privilegi sufficienti a creare l'inode, o
+    il filesystem su cui si è cercato di creare \func{pathname} non supporta
+    l'operazione.
+  \item[\macro{EINVAL}] Il valore di \var{mode} non indica un file, una fifo o
+    un dipositivo.
+  \item[\macro{EEXIST}] \param{pathname} esiste già o è un link simbolico.
   \end{errlist}
-  ed inoltre anche \macro{EFAULT}, \macro{ENAMETOOLONG}, \macro{ENOENT},
-  \macro{ENOTDIR}, \macro{ENOMEM}, \macro{ELOOP}, \macro{EROFS}.}
+  ed inoltre anche \macro{EFAULT}, \macro{EACCESS}, \macro{ENAMETOOLONG},
+  \macro{ENOENT}, \macro{ENOTDIR}, \macro{ENOMEM}, \macro{ELOOP},
+  \macro{ENOSPC}, \macro{EROFS}.}
 \end{functions}
 
-
+La funzione permette di creare un file speciale, ma si può usare anche per
+creare file normali e fifo; l'argomento \param{mode} specifica il tipo di file
+che si vuole creare ed i relativi permessi, secondo i valori riportati in
+\tabref{tab:file_mode_flags}, che vanno combinato come OR binario. I permessi
+sono comunque modificati nella maniera usuale dal valore di \var{umask} (si
+veda \secref{sec:file_umask}.
+
+Per il tipo di file può essere specificato solo uno fra: \macro{S\_IFREG} per
+un file normale (che sarà creato vuoto), \macro{S\_IFBLK} per un device a
+blocchi, \macro{S\_IFCHR} per un device a caratteri e \macro{S\_IFIFO} per una
+fifo. Un valore diverso comporterà l'errore \macro{EINVAL}. Qualora si sia
+specificato in \param{mode} un file di dispositivo, il valore di \param{dev}
+viene usato per indicare a quale dispositivo si fa riferimento. 
+
+Solo l'amministratore può creare un file di dispositivo o un file regolare
+usando questa funzione; ma in Linux\footnote{la funzione non è prevista dallo
+  standard POSIX, e deriva da SVr4, con appunto questa differenza e diversi
+  codici di errore.} l'uso per la creazione di una fifo è consentito anche
+agli utenti normali.
+
+I nuovi inode creati con \func{mknod} apparterranno al proprietario e al
+gruppo del processo che li 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 \secref{sec:file_ownership}) in cui si va a creare
+l'inode.
+
+Per creare una fifo (un file speciale, su cui torneremo in dettaglio in
+\secref{sec:ipc_named_pipe}) lo standard POSIX specifica l'uso della funzione
+\func{mkfifo}, il cui prototipo è:
 \begin{functions}
-  \headdecl{sys/types.h}
-  \headdecl{sys/stat.h}
-  \funcdecl{int mkfifo(const char *pathname, mode\_t mode)} 
+  \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:
-  \begin{errlist}
-  \item[\macro{EPERM}] Il filesystem non supporta la cancellazione di
-    directory, oppure la directory che contiene \var{dirname} ha lo sticky bit
-    settato e l'\textit{effective user id} del processo non corrisponde al
-    proprietario della directory. 
-  \item[\macro{EACCESS}] 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
-    \var{dirname}.
-  \item[\macro{EBUSY}] La directory specificata è la directory di lavoro o la
-    radice di qualche processo.
-  \item[\macro{ENOTEMPTY}] La directory non è vuota.
-  \end{errlist}
-  ed inoltre anche \macro{EFAULT}, \macro{ENAMETOOLONG}, \macro{ENOENT},
-  \macro{ENOTDIR}, \macro{ENOMEM}, \macro{ELOOP}, \macro{EROFS}.}
+    errore, nel qual caso \var{errno} assumerà i valori \macro{EACCESS},
+    \macro{EEXIST}, \macro{ENAMETOOLONG}, \macro{ENOENT}, \macro{ENOSPC},
+    \macro{ENOTDIR} e\macro{EROFS}.}
 \end{functions}
-
+\noindent 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 \var{umask}.
 
 
 
@@ -582,7 +596,7 @@ processi devono creare i file usando le apposite funzioni.
 
 Per accedere al contenuto delle directory si usano i cosiddetti
 \textit{directory streams} (chiamati così per l'analogia con i file stream di
-\capref{che:file_std_interface}); la funzione \func{opendir} apre uno di
+\capref{cha:files_std_interface}); la funzione \func{opendir} apre uno di
 questi stream e la funzione \func{readdir} legge il contenuto della directory,
 i cui elementi sono le \textit{directory entry} (da distinguersi da quelle
 della cache di cui parlavamo in \secref{sec:file_vfs}) in una opportuna
@@ -651,47 +665,61 @@ funzione 
 Una seconda funzione simile è \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 \macro{PWD},
-che essendo costruita dalla shell può contenere anche dei riferimenti
-simbolici; nel caso di \func{getcwd} infatti, essendo il pathname ricavato
-risalendo all'indietro l'albero della directory, si perderebbe traccia di ogni
-passaggio attraverso eventuali pathname.
-
-Altre due funzioni, \func{chdir} e \func{fchdir}, vengono usate, come dice il
-nome (che deriva da \textit{change directory}), per cambiare la directory di
-lavoro corrente. Dato che anche le directory sono file, è possibile riferirsi
-ad esse anche tramite il file descriptor dell'interfaccia a basso livello, e
-non solo tramite il filename, i prototipi di queste funzioni sono:
-\begin{functions}
-  \headdecl{unistd.h} 
-  \funcdecl{int chdir(const char *path)} 
-  Cambia la directory di lavoro corrente a quella specificata dal pathname
-  contenuto nella stringa \var{path}.
-  
-  \funcdecl{int fchdir(int fd)} Analoga alla precedente, ma usa un file
-  descriptor invece del pathname.
+che essendo costruita dalla shell può contenere un pathname comprendente anche
+con dei link simbolici. Usando \func{getcwd} infatti, essendo il
+pathname ricavato risalendo all'indietro l'albero della directory, si
+perderebbe traccia di ogni passaggio attraverso eventuali link simbolici.
+
+Per cambiare la directory di lavoro corrente si può usare la funzione
+\func{chdir} (omonima dell'analogo comando di shell) il cui nome sta appunto
+per \textit{change directory}), il suo prototipo è:
+\begin{prototype}{unistd.h}{int chdir(const char *pathname)} 
+  Cambia la directory di lavoro corrente in \param{pathname}.
   
-  \bodydesc{Entrambe le funzioni restituiscono zero in caso di successo
-    e -1 per un errore, in caso di errore \var{errno} viene settata per
-    \func{chdir} ai valori:
+  \bodydesc{La funzione restituisce 0 in caso di successo e -1 per un errore,
+    nel qual caso \var{errno} viene settata a:
   \begin{errlist}
-  \item[\macro{ENOTDIR}] Uno dei componenti di \param{path} non è una
-    directory.
+  \item[\macro{ENOTDIR}] Non si è specificata una directory.
   \item[\macro{EACCESS}] Manca il permesso di ricerca su uno dei componenti di
     \param{path}.
   \end{errlist}
   ed inoltre \macro{EFAULT}, \macro{ENAMETOOLONG}, \macro{ENOENT},
-  \macro{ENOMEM}, \macro{ELOOP} e \macro{EIO}. Per \func{fchdir} invece gli
-  errori sono \macro{EBADF} e \macro{EACCES}.}
-\end{functions}
+  \macro{ENOMEM}, \macro{ELOOP} e \macro{EIO}.}
+\end{prototype}
+\noindent ed ovviamente \param{pathname} deve indicare una directory per la
+quale si hanno i permessi di accesso.
+
+Dato che anche le directory sono file, è possibile riferirsi ad esse anche
+tramite il file descriptor, e non solo tramite il filename, per fare questo si
+usa \func{fchdir}, il cui prototipo è:
+\begin{prototype}{unistd.h}{int fchdir(int fd)} 
+  Identica a \func{chdir}, ma usa il file descriptor \param{fd} invece del
+  pathname.
+  
+  \bodydesc{La funzione restituisce zero in caso di successo e -1 per un
+    errore, in caso di errore \var{errno} viene settata ai valori
+    \macro{EBADF} o \macro{EACCES}.}
+\end{prototype}
+\noindent anche in questo caso \param{fd} deve essere un file descriptor
+valido che fa riferimento ad una directory. Inoltre l'unico errore di accesso
+possibile (tutti gli altri sarebbero occorsi all'apertura di \func{fd}), è
+quello in cui il processo non ha il permesso di accesso alla directory
+specificata da \param{fd}.
 
 
 
 \subsection{I file temporanei}
 \label{sec:file_temp_file}
 
-Un'altra serie di funzioni definite dalle librerie standard del C sono quelle
-che riguardano la creazione di file temporanei. 
+In molte occasioni è utile poter creare dei file temporanei; benchè la cosa
+sembri semplice in realtà il problema è più sottile di quanto non appaia a
+prima vista. Infatti anche se sembrerebbe banale generare un nome a caso e
+creare il file dopo aver controllato che questo non esista, nel momento fra il
+controllo e la creazione si ha giusto lo spazio per una \textit{race
+  condition} (si ricordi quanto visto in \secref{sec:proc_race_cond}).
 
+Per questo motivo il kernel le \acr{glibc} provvedono una serie di funzioni da
+utilizzare per la gestione dei file temporanei.
 
 
 
@@ -1449,7 +1477,7 @@ bit \acr{sgid} settato allora viene usata la seconda opzione.
 
 Usare la semantica BSD ha il vantaggio che il \acr{gid} viene sempre
 automaticamente propagato, restando coerente a quello della directory di
-partenza, in tutte le sottodirectory. La semantica SVR4 offre una maggiore
+partenza, in tutte le sottodirectory. La semantica SVr4 offre una maggiore
 possibilità di scelta, ma per ottenere lo stesso risultato necessita che per
 le nuove directory venga anche propagato anche il bit \acr{sgid}. Questo è
 comunque il comportamento di default di \func{mkdir}, ed é in questo modo ad