Completate pure le fifo.
authorSimone Piccardi <piccardi@gnulinux.it>
Tue, 2 Jul 2002 22:23:58 +0000 (22:23 +0000)
committerSimone Piccardi <piccardi@gnulinux.it>
Tue, 2 Jul 2002 22:23:58 +0000 (22:23 +0000)
fileunix.tex
ipc.tex

index 40d022815a8fcd909a6e729af3538ed765c63f81..56e70435f4d2934b1e1abdeffe54b4ce5e82e703 100644 (file)
@@ -221,7 +221,7 @@ sempre il file descriptor con il valore pi
     \hline % modalità di accesso al file
     \macro{O\_RDONLY} & apre il file in sola lettura. \\
     \macro{O\_WRONLY} & apre il file in sola scrittura. \\
     \hline % modalità di accesso al file
     \macro{O\_RDONLY} & apre il file in sola lettura. \\
     \macro{O\_WRONLY} & apre il file in sola scrittura. \\
-    \macro{O\_RDWR} & apre il file lettura/scrittura. \\
+    \macro{O\_RDWR} & apre il file in lettura/scrittura. \\
     \hline % modalità di apertura del file
     \hline
     \macro{O\_CREAT} & se il file non esiste verrà creato, con le regole di
     \hline % modalità di apertura del file
     \hline
     \macro{O\_CREAT} & se il file non esiste verrà creato, con le regole di
@@ -232,8 +232,8 @@ sempre il file descriptor con il valore pi
     \func{open} con \macro{EEXIST}. \\
     \macro{O\_NONBLOCK} & apre il file in modalità non bloccante. Questo
     valore specifica anche una modalità di operazione (vedi sotto), e 
     \func{open} con \macro{EEXIST}. \\
     \macro{O\_NONBLOCK} & apre il file in modalità non bloccante. Questo
     valore specifica anche una modalità di operazione (vedi sotto), e 
-    comporta che \func{open} ritorni immediatamente (torneremo su
-    questo in \secref{sec:file_noblocking}). \\
+    comporta che \func{open} ritorni immediatamente (l'opzione ha senso 
+    solo per le fifo, torneremo questo in \secref{sec:ipc_named_pipe}). \\
     \macro{O\_NOCTTY} & se \var{pathname} si riferisce ad un device di
     terminale, questo non diventerà il terminale di controllo, anche se il
     processo non ne ha ancora uno (si veda \secref{sec:sess_xxx}). \\
     \macro{O\_NOCTTY} & se \var{pathname} si riferisce ad un device di
     terminale, questo non diventerà il terminale di controllo, anche se il
     processo non ne ha ancora uno (si veda \secref{sec:sess_xxx}). \\
@@ -265,10 +265,11 @@ sempre il file descriptor con il valore pi
     file. Può causare corruzione del file con NFS se più di un processo scrive
     allo stesso tempo.\footnotemark\\
     \macro{O\_NONBLOCK} & il file viene aperto in modalità non bloccante per
     file. Può causare corruzione del file con NFS se più di un processo scrive
     allo stesso tempo.\footnotemark\\
     \macro{O\_NONBLOCK} & il file viene aperto in modalità non bloccante per
-    le operazioni di I/O: questo significa il fallimento di  \func{read} in
-    assenza di dati da leggere e quello di \func{write} in caso di 
-    impossibilità di scrivere immediatamente. L'opzione è effettiva solo per
-    le fifo e per alcuni file di dispositivo. \\
+    le operazioni di I/O (che tratteremo in \secref{sec:file_noblocking}): 
+    questo significa il fallimento di \func{read} in assenza di dati da 
+    leggere e quello di \func{write} in caso di impossibilità di scrivere 
+    immediatamente. Questa modalità ha senso solo per le fifo e per alcuni 
+    file di dispositivo. \\
     \macro{O\_NDELAY} & in Linux\footnotemark\ è sinonimo di 
     \macro{O\_NONBLOCK}.\\
     \macro{O\_ASYNC} & apre il file per l'I/O in modalità
     \macro{O\_NDELAY} & in Linux\footnotemark\ è sinonimo di 
     \macro{O\_NONBLOCK}.\\
     \macro{O\_ASYNC} & apre il file per l'I/O in modalità
@@ -295,9 +296,9 @@ sempre il file descriptor con il valore pi
   di usare un file con un nome univoco e la funzione \func{link} per
   verificarne l'esistenza.}  
 
   di usare un file con un nome univoco e la funzione \func{link} per
   verificarne l'esistenza.}  
 
-\footnotetext[3]{Denial of Service, si chiamano così attacchi miranti ad
-  impedire un servizio causando una qualche forma di carico eccessivo per il
-  sistema, che resta bloccato nelle risposte all'attacco.}
+\footnotetext[3]{\textit{Denial of Service}, si chiamano così attacchi miranti
+  ad impedire un servizio causando una qualche forma di carico eccessivo per
+  il sistema, che resta bloccato nelle risposte all'attacco.}
 
 \footnotetext[4]{il problema è che NFS non supporta la scrittura in append, ed
   il kernel deve simularla, ma questo comporta la possibilità di una race
 
 \footnotetext[4]{il problema è che NFS non supporta la scrittura in append, ed
   il kernel deve simularla, ma questo comporta la possibilità di una race
diff --git a/ipc.tex b/ipc.tex
index 3c30111cebf747b7316715bdcc672a4e373b441c..cd9c68fed1b9596b3bf07e68eb041f09b5aa82df 100644 (file)
--- a/ipc.tex
+++ b/ipc.tex
@@ -101,6 +101,16 @@ processi possano condividere i file descriptor della pipe, e per questo essi
 devono comunque derivare da uno stesso processo padre che ha aperto la pipe,
 o, più comunemente, essere nella relazione padre/figlio.
 
 devono comunque derivare da uno stesso processo padre che ha aperto la pipe,
 o, più comunemente, essere nella relazione padre/figlio.
 
+A differenza di quanto avviene con i file normali la lettura da una pipe può
+essere bloccante (qualora non siano presenti dati), inoltre se si legge da una
+pipe il cui capo in scrittura è stato chiuso, si avrà la ricezione di un EOF
+(vale a dire che la funzione \func{read} ritornerà restituendo 0).  Se invece
+si esegue una scrittura su una pipe il cui capo in lettura non è aperto il
+processo riceverà il segnale \macro{EPIPE}, e la funzione di scrittura
+restituirà un errore di \macro{EPIPE} (al ritorno del manipolatore, o qualora
+il segnale sia ignorato o bloccato).
+
+
 
 \subsection{Un esempio dell'uso delle pipe}
 \label{sec:ipc_pipe_use}
 
 \subsection{Un esempio dell'uso delle pipe}
 \label{sec:ipc_pipe_use}
@@ -158,8 +168,8 @@ duplicazione dei file descriptor che abbiamo trattato in
 \secref{sec:file_dup}, in particolare di \func{dup2}. È attraverso queste
 funzioni infatti che è possibile dirottare gli stream standard dei processi
 (che abbiamo visto in \secref{sec:file_std_descr} e
 \secref{sec:file_dup}, in particolare di \func{dup2}. È attraverso queste
 funzioni infatti che è possibile dirottare gli stream standard dei processi
 (che abbiamo visto in \secref{sec:file_std_descr} e
-\secref{sec:file_std_stream}) sulla pipe. In \figref{fig:ipc_barcode_code}
-abbiamo riportato il corpo del programm, il cui codice completo è disponibile
+\secref{sec:file_std_stream}) sulla pipe. In \figref{fig:ipc_barcodepage_code}
+abbiamo riportato il corpo del programma, il cui codice completo è disponibile
 nel file \file{BarCodePage.c} che si trova nella directory dei sorgenti.
 
 
 nel file \file{BarCodePage.c} che si trova nella directory dei sorgenti.
 
 
@@ -219,7 +229,7 @@ int main(int argc, char *argv[], char *envp[])
   \normalsize 
   \caption{Sezione principale del codice del \textit{CGI} 
     \file{BarCodePage.c}.}
   \normalsize 
   \caption{Sezione principale del codice del \textit{CGI} 
     \file{BarCodePage.c}.}
-  \label{fig:ipc_barcode_code}
+  \label{fig:ipc_barcodepage_code}
 \end{figure}
 
 La prima operazione del programma (\texttt{\small 4--12}) è quella di creare
 \end{figure}
 
 La prima operazione del programma (\texttt{\small 4--12}) è quella di creare
@@ -227,10 +237,10 @@ le due pipe che serviranno per la comunicazione fra i due comandi utilizzati
 per produrre il codice a barre; si ha cura di controllare la riuscita della
 chiamata, inviando in caso di errore un messaggio invece dell'immagine
 richiesta.\footnote{la funzione \func{WriteMess}, non è riportata in
 per produrre il codice a barre; si ha cura di controllare la riuscita della
 chiamata, inviando in caso di errore un messaggio invece dell'immagine
 richiesta.\footnote{la funzione \func{WriteMess}, non è riportata in
-  \secref{fig:ipc_barcode_code}; essa si incarica semplicemente di formattare
-  l'uscita alla maniera dei CGI, aggiungendo l'opportuno \textit{mime type}, e
-  formattando il messaggio in HTML, in modo che quest'ultimo possa essere
-  visualizzato correttamente da un browser.}
+  \secref{fig:ipc_barcodepage_code}; essa si incarica semplicemente di
+  formattare l'uscita alla maniera dei CGI, aggiungendo l'opportuno
+  \textit{mime type}, e formattando il messaggio in HTML, in modo che
+  quest'ultimo possa essere visualizzato correttamente da un browser.}
 
 Una volta create le pipe, il programma può creare (\texttt{\small 13-17}) il
 primo processo figlio, che si incaricherà (\texttt{\small 19--25}) di eseguire
 
 Una volta create le pipe, il programma può creare (\texttt{\small 13-17}) il
 primo processo figlio, che si incaricherà (\texttt{\small 19--25}) di eseguire
@@ -344,8 +354,8 @@ attendendo la terminazione del processo ad essa associato.
 \func{popen}.
 
 Per illustrare l'uso di queste due funzioni riprendiamo il problema
 \func{popen}.
 
 Per illustrare l'uso di queste due funzioni riprendiamo il problema
-precedente: il programma mostrato in \figref{fig:ipc_barcode_code} per quanto
-funzionante, è (volutamente) codificato in maniera piuttosto complessa,
+precedente: il programma mostrato in \figref{fig:ipc_barcodepage_code} per
+quanto funzionante, è (volutamente) codificato in maniera piuttosto complessa,
 inoltre nella pratica sconta un problema di \cmd{gs} che non è in
 grado\footnote{nella versione GNU Ghostscript 6.53 (2002-02-13).} di
 riconoscere correttamente l'encapsulated postscript, per cui deve essere usato
 inoltre nella pratica sconta un problema di \cmd{gs} che non è in
 grado\footnote{nella versione GNU Ghostscript 6.53 (2002-02-13).} di
 riconoscere correttamente l'encapsulated postscript, per cui deve essere usato
@@ -380,16 +390,16 @@ dimensioni corrette attraverso vari programmi di manipolazione (\cmd{pnmcrop},
 
 In questo caso però occorre eseguire in sequenza ben quattro comandi diversi,
 inviando l'output di ciascuno all'input del successivo, per poi ottenere il
 
 In questo caso però occorre eseguire in sequenza ben quattro comandi diversi,
 inviando l'output di ciascuno all'input del successivo, per poi ottenere il
-risultato finale sullo standard output; un caso classico di utilizzazione
+risultato finale sullo standard output: un caso classico di utilizzazione
 delle pipe, in cui l'uso di \func{popen} e \func{pclose} permette di
 semplificare notevolmente la stesura del codice.
 
 Nel nostro caso, dato che ciascun processo deve scrivere il suo output sullo
 standard input del successivo, occorrerà usare \func{popen} aprendo la pipe in
 scrittura. Il codice del nuovo programma è riportato in
 delle pipe, in cui l'uso di \func{popen} e \func{pclose} permette di
 semplificare notevolmente la stesura del codice.
 
 Nel nostro caso, dato che ciascun processo deve scrivere il suo output sullo
 standard input del successivo, occorrerà usare \func{popen} aprendo la pipe in
 scrittura. Il codice del nuovo programma è riportato in
-\figref{fig:ipc_barcode2_code}.  Come si può notare l'ordine di invocazione
-dei programmi è l'inverso di quello in cui ci si aspetta vengano
-effettivamente eseguiti. Questo non comporta nessun problema; infatti la
+\figref{fig:ipc_barcode_code}.  Come si può notare l'ordine di invocazione dei
+programmi è l'inverso di quello in cui ci si aspetta che vengano
+effettivamente eseguiti. Questo non comporta nessun problema dato che la
 lettura su una pipe è bloccante, per cui ciascun processo, per quanto lanciato
 per primo, si bloccherà in attesa di ricevere sullo standard input il
 risultato dell'elaborazione del precendente, benchè quest'ultimo venga
 lettura su una pipe è bloccante, per cui ciascun processo, per quanto lanciato
 per primo, si bloccherà in attesa di ricevere sullo standard input il
 risultato dell'elaborazione del precendente, benchè quest'ultimo venga
@@ -427,12 +437,6 @@ int main(int argc, char *argv[], char *envp[])
         pclose((pipe[i]));
     }
     exit(0);
         pclose((pipe[i]));
     }
     exit(0);
-}
-void WriteMess(char *mess)
-{
-    printf("Content-type: text/html\n\n");
-    perror(mess);
-    printf("<br>\n");
 }
     \end{lstlisting}
   \end{minipage} 
 }
     \end{lstlisting}
   \end{minipage} 
@@ -472,33 +476,47 @@ Come accennato in \secref{sec:ipc_pipes} il problema delle \textit{pipe} 
 esse possono essere utilizzate solo da processi con un progenitore comune o
 nella relazione padre/figlio; per superare questo problema lo standard POSIX.1
 ha definito dei nuovi oggetti, le \textit{fifo}, che hanno le stesse
 esse possono essere utilizzate solo da processi con un progenitore comune o
 nella relazione padre/figlio; per superare questo problema lo standard POSIX.1
 ha definito dei nuovi oggetti, le \textit{fifo}, che hanno le stesse
-caratteristiche delle pipe, ma invece che essere struttura interne del kernel
-visibili solo attraverso un file descriptor comune, possono essere viste
-attraverso un inode che risiede sul filesystem.
-
-Utilizzando una fifo tutti i dati passeranno attraverso un apposito buffer nel
-kernel, senza transitare dal filesystem, l'inode serve solo a fornire un punto
-d'appoggio per i vari processi che permetta loro di accedere alla stessa
-fifo.  
-
-
-
-
-Abbiamo già visto in \secref{sec:file_mknod} le modalità che permettono di
-creare una fifo, attraverso le funzioni \func{mknod} e \func{mkfifo}; per
-utilizzarle un processo non avrà che da aprire il relativo file in lettura o
-scrittura (a seconda della direzione che si vuole dare ai dati).
-
-che invece possono risiedere
-sul filesystem, e che i processi possono usare per le comunicazioni senza
-dovere per forza essere in relazione diretta.
-
-
+caratteristiche delle pipe, ma che invece di essere strutture interne del
+kernel, visibili solo attraverso un file descriptor, sono accessibili
+attraverso un inode che risiede sul filesystem, così che i processi le possono
+usare senza dovere per forza essere in una relazione di \textsl{parentela}.
+
+Utilizzando una \textit{fifo} tutti i dati passeranno, come per le pipe,
+attraverso un apposito buffer nel kernel, senza transitare dal filesystem;
+l'inode allocato sul filesystem serve infatti solo a fornire un punto di
+riferimento per i processi, che permetta loro di accedere alla stessa fifo; il
+comportamento delle funzioni di lettura e scrittura è identico a quello
+illustrato per le pipe in \secref{sec:ipc_pipes}.
+
+Abbiamo già visto in \secref{sec:file_mknod} le funzioni \func{mknod} e
+\func{mkfifo} che permettono di creare una fifo; per utilizzarne una un
+processo non avrà che da aprire il relativo file speciale o in lettura o
+scrittura; nel primo caso sarà collegato al capo di uscita della fifo, e dovrà
+leggere, nel secondo al capo di ingresso, e dovrà scrivere.
+
+Il kernel crea una sigola pipe per ciascuna fifo che sia stata aperta, che può
+essere acceduta contemporaneamente da più processi, sia in lettura che in
+scrittura. Dato che per funzionare deve essere aperta in entrambe le
+direzioni, per una fifo di norma la funzione \func{open} si blocca se viene
+eseguita quando l'altro capo non è aperto.
+
+Le fifo però possono essere anche aperte in modalità \textsl{non-bloccante},
+nel qual caso l'apertura del capo in lettura avrà successo solo quando anche
+l'altro capo è aperto, mentre l'apertura del capo in scrittura restituirà
+l'errore di \macro{ENXIO} fintanto che non verrà aperto il capo in lettura.
+
+In Linux\footnote{lo standard POSIX lascia indefinito questo comportamento.} è
+possibile aprire le fifo anche in lettura/scrittura, operazione che avrà
+sempre successo qualunque sia la modalità di apertura (bloccante e non
+bloccante); questo può essere utilizzato per aprire comunque una fifo in
+scrittura anche se non ci sono ancora processi il lettura; è possibile anche
+usare la fifo all'interno di un solo processo, nel qual caso però occorre
+stare molto attenti alla possibili deadlock.\footnote{se si cerca di leggere
+  da una fifo che non contiene dati si avrà un deadlock immediato, dato che il
+  processo si blocca e non potrà quindi mai eseguire le funzioni di
+  scrittura.}
 
 
 
 
-Per poter superare il problema delle \textit{pipe}, illustrato in
-\secref{sec:ipc_pipes}, che ne consente l'uso solo fra processi con un
-progenitore comune o nella relazione padre/figlio,
   
 \section{La comunicazione fra processi di System V}
 \label{sec:ipc_sysv}
   
 \section{La comunicazione fra processi di System V}
 \label{sec:ipc_sysv}