\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
\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}). \\
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à
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
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}
\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.
\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
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
\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
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
-\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
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}
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}