From 30a6a42996cb5bf0d7c0b2b607743893dc964cdd Mon Sep 17 00:00:00 2001 From: Simone Piccardi Date: Tue, 11 Jun 2002 21:52:04 +0000 Subject: [PATCH] Sistemata bibliografia, aggiunte ad ioctl e qualcosa in piu` sulle pipe --- biblio.bib | 2 +- fileunix.tex | 81 +++++++++++++++++++++++++++++++++++++++------------- ipc.tex | 49 ++++++++++++++++++++++++------- 3 files changed, 100 insertions(+), 32 deletions(-) diff --git a/biblio.bib b/biblio.bib index 3004c7d..e590a1f 100644 --- a/biblio.bib +++ b/biblio.bib @@ -63,7 +63,7 @@ OPTannote = {} } @Book{LinDevDri, - author = {A. Rubini and F. Bouhet}, + author = {A. Rubini and J. Corbet}, editor = {O'Reilly}, title = {Linux Device Driver}, publisher = {O'Reilly}, diff --git a/fileunix.tex b/fileunix.tex index a8a7d78..8428e10 100644 --- a/fileunix.tex +++ b/fileunix.tex @@ -931,8 +931,8 @@ effettuare una \func{close}, perdendo l'atomicit L'uso principale di queste funzioni è per la redirezione dell'input e dell'output fra l'esecuzione di una \func{fork} e la successiva \func{exec}; diventa così possibile associare un file (o una pipe) allo standard input o -allo standard output, torneremo su questo uso in \secref{sec:ipc_pipes} quando -tratteremo le pipe. +allo standard output, torneremo su questo uso in \secref{sec:ipc_pipe_use} +quando tratteremo le pipe. \subsection{La funzione \func{fcntl}} @@ -984,7 +984,8 @@ valori di \tabref{tab:file_open_flags}). \item[\macro{F\_SETFL}] setta il \textit{file status flag} al valore specificato da \param{arg}, possono essere settati solo i bit riportati - nella terza sezione di \tabref{tab:file_open_flags} (da verificare). + nella terza sezione di \tabref{tab:file_open_flags}.\footnote{NdA da + verificare.} \item[\macro{F\_GETLK}] se un file lock è attivo restituisce nella struttura \param{lock} la struttura \type{flock} che impedisce l'acquisizione del blocco, altrimenti setta il campo \var{l\_type} a \macro{F\_UNLCK} (per i @@ -1007,19 +1008,21 @@ valori \item[\macro{F\_SETOWN}] setta il processo o process group che riceverà i segnali \macro{SIGIO} e \macro{SIGURG} per gli eventi associati al file descriptor \var{fd}. I process group sono settati usando valori negativi. -\item[\macro{F\_GETSIG}] restituisce il segnale mandato quando ci sono dati - disponibili in input su un file descriptor aperto o settato in I/O - asincrono. Il valore 0 indica il default (che è \macro{SIGIO}), un valore - diverso da zero indica il segnale richiesto, (che può essere lo stesso - \macro{SIGIO}).\footnote{in questo caso al manipolatore del segnale, se - installato come \var{sa\_sigaction} con \macro{SA\_SIGINFO}, vengono rese - disponibili informazioni ulteriori informazioni (vedi - \secref{sec:sig_sigaction} e \secref{sec:file_asyncronous_io})}. +\item[\macro{F\_GETSIG}] restituisce il valore del segnale mandato quando ci + sono dati disponibili in input su un file descriptor aperto o settato in I/O + asincrono. Il valore 0 indica il valore default (che è \macro{SIGIO}), un + valore diverso da zero indica il segnale richiesto, (che può essere lo + stesso \macro{SIGIO}). \item[\macro{F\_SETSIG}] setta il segnale da inviare quando diventa possibile - effettuare I/O sul file descriptor. Il valore zero indica il default - (\macro{SIGIO}), ogni altro valore permette di rendere disponibile al - manipolatore del segnale ulteriori informazioni se si è usata - \macro{SA\_SIGINFO}. + effettuare I/O sul file descriptor in caso di I/O asincrono. Il valore zero + indica di usare il segnale di default, \macro{SIGIO}. Un altro valore + (compreso lo stesso \macro{SIGIO}) specifica il segnale voluto; l'uso di un + valore diverso da zero permette inoltre, se si è installato il manipolatore + del segnale come \var{sa\_sigaction} usando \macro{SA\_SIGINFO}, (vedi + \secref{sec:sig_sigaction}), di rendere disponibili al manipolatore + informazioni ulteriori informazioni riguardo il file che ha generato il + segnale attraverso i valori restituiti in \var{siginfo\_t} (come vedremo in + \secref{sec:file_asyncronous_io}). \end{basedescript} La maggior parte delle funzionalità di \func{fcntl} sono troppo avanzate per @@ -1053,14 +1056,16 @@ per ogni singolo dispositivo. Il prototipo di questa funzione \begin{prototype}{sys/ioctl.h}{int ioctl(int fd, int request, ...)} Manipola il dispositivo sottostante, usando il parametro \param{request} per specificare l'operazione richiesta e il terzo parametro (usualmente di tipo - \param{char * argp}) per il trasferimento dell'informazione necessaria. + \param{char * argp} o \param{int argp}) per il trasferimento + dell'informazione necessaria. \bodydesc{La funzione nella maggior parte dei casi ritorna 0, alcune operazioni usano però il valore di ritorno per restituire informazioni. In caso di errore viene sempre restituito -1 e \var{errno} viene settata ad uno dei valori seguenti: \begin{errlist} - \item[\macro{ENOTTY}] il file \param{fd} non è associato con un device. + \item[\macro{ENOTTY}] il file \param{fd} non è associato con un device, o la + richiesta non è applicabile all'oggetto a cui fa riferimento \param{fd}. \item[\macro{EINVAL}] gli argomenti \param{request} o \param{argp} non sono validi. \end{errlist} @@ -1069,9 +1074,45 @@ per ogni singolo dispositivo. Il prototipo di questa funzione La funzione serve in sostanza per fare tutte quelle operazioni che non si adattano al design dell'architettura dei file e che non è possibile effettuare -con le funzioni esaminate finora. Per questo motivo non è possibile fare altro -che darne una descrizione generica; torneremo ad esaminarla in seguito, quando -si tratterà di applicarla ad alcune problematiche specifiche. +con le funzioni esaminate finora. Esse vengono selezionate attraverso il +valore di \param{request} e gli eventuali risultati possono essere restituiti +sia attraverso il valore di ritorno che attraverso il terzo argomento +\param{argp}. Sono esempi delle operazioni gestite con una \func{ioctl}: +\begin{itemize*} +\item il cambiamento dei font di un terminale. +\item l'esecuzione di una traccia audio di un CDROM. +\item i comandi di avanti veloce e riavvolgimento di un nastro. +\item il comando di espulsione di un dispositivo rimovibile. +\item il settaggio della velocità trasmissione di una linea seriale. +\item il settaggio della frequenza e della durata dei suoni emessi dallo + speaker. +\end{itemize*} + +In generale ogni dispositivo ha un suo insieme di possibili diverse operazioni +effettuabili attraverso \func{ioctl}, che sono definite nell'header file +\file{sys/ioctl.h}, e devono essere usate solo sui dispositivi cui fanno +riferimento. Infatti anche se in genere i valori di \param{request} sono +opportunamente differenziati a seconda del dispositivo\footnote{il kernel usa + un apposito \textit{magic number} per distinguere ciascun dispositivo nella + definizione delle macro da usare per \param{request}, in modo da essere + sicuri che essi siano sempre diversi, ed il loro uso causi al più un errore. + Si veda il capitolo quinto di \cite{LinDevDri} per una trattazione + dettagliata dell'argomento.} in alcuni casi, relativi a valori assegnati +prima che questa differenziazione diventasse pratica corrente si potrebbe +avere + +Per questo motivo non è possibile fare altro che darne una descrizione +generica; torneremo ad esaminare in seguito quelle relative ad alcuni casi +specifici (ad esempio la gestione dei terminali è effettuata attraverso +\func{ioctl} in quasi tutte le implementazioni di Unix), qui riportiamo solo i +valori che sono definiti per ogni file: +\begin{basedescript}{\desclabelwidth{2.0cm}} +\item[\macro{FIOCLEX}] Setta il bit di \textit{close on exec}. +\item[\macro{FIONCLEX}] Cancella il bit di \textit{close on exec}. +\item[\macro{FIOASYNC}] Abilita l'I/O asincrono. +\item[\macro{FIONBIO}] Abilità l'I/O in modalità non bloccante. +\end{basedescript} +relativi ad operazioni comunque eseguibili anche attraverso \func{fcntl}. %%% Local Variables: diff --git a/ipc.tex b/ipc.tex index b8c703a..352a719 100644 --- a/ipc.tex +++ b/ipc.tex @@ -31,14 +31,15 @@ evoluto. \subsection{Le \textit{pipe} standard} \label{sec:ipc_pipes} -Le \textit{pipe} nascono sostanzialmente con Unix, e sono il primo, ed uno dei -più usati, meccanismi di comunicazione fra processi. Si tratta in sostanza uno -speciale tipo di file\footnote{più precisamente un file descriptor; le pipe - sono create dal kernel e non risiedono su disco.} in cui un processo scrive -ed un altro legge. Si viene così a costituire un canale di comunicazione fra i -due processi, nella forma di un \textsl{tubo} (da cui il nome) in cui uno dei -processi immette dati che poi arriveranno all'altro. - +Le \textit{pipe} nascono sostanzialmente con Unix, e sono il primo, e tuttora +uno dei più usati, meccanismi di comunicazione fra processi. Si tratta in +sostanza di uno speciale tipo di file descriptor, più precisamente una coppia +di file descriptor,\footnote{si tenga presente che le pipe sono oggetti creati + dal kernel e non risiedono su disco.} su cui da una parte si scrive e da +un'altra si legge. Si viene così a costituire un canale di comunicazione +tramite i due file descriptor, nella forma di un \textsl{tubo} (da cui il +nome) in cui in genere un processo immette dati che poi arriveranno ad un +altro. La funzione che permette di creare una pipe è appunto \func{pipe}; il suo prototipo è: @@ -94,16 +95,42 @@ Tutto ci comunicazione fra processi attraverso una pipe, utilizzando le ordinarie proprietà dei file, ma ci mostra anche qual'è il principale\footnote{Stevens riporta in APUE come limite anche il fatto che la comunicazione è - unidirezionale, in realtà questo è un limite facilemente risolvibile usando + unidirezionale, in realtà questo è un limite facilmente risolvibile usando una coppia di pipe.} limite nell'uso delle pipe. È necessario infatti che i 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. + + +\subsection{Un esempio dell'uso delle pipe} +\label{sec:ipc_pipe_use} + Per capire meglio il funzionamento di una pipe faremo un esempio di quello che è il loro uso più comune, analogo a quello effettuato della shell, e che -consiste nell'inviare l'output di un processo (usando lo standard output) -sull'input di un'altro. +consiste nell'inviare l'output di un processo (lo standard output) sull'input +di un'altro. Realizzaremo il programma nella forma di un +\textit{cgi-bin}\footnote{breve descrizione, da fare, di cosa è un cgi-bin.} +per apache, che genera una immagine JPEG di un codice a barre, specificato +come parametro di input. + +Per fare questo useremo i programmi \cmd{barcode} e \cmd{gs}, il primo infatti +è in grado di generare immagini postscript di codici a barre corrispondenti ad +una qualunque stringa, data come parametro, mentre il secondo è in grado di +convertire un file postscript in una immagine JPEG. Usando l'ouptut del primo +come input del secondo attraverso una pipe potremo generare immagini JPEG del +codice a barre di una stringa qualunque. + +Si potrebbe obiettare che sarebbe molto più semplice ottenere lo stesso +risultato salvando il tutto in un file temporaneo, ma si dovrebbe comunque +risolvere il problema di come comunicare il nome di questo file da un processo +all'altro, dato che utilizzare lo stesso file porterebbe ad inevitabili +sovrascritture nell'accavallarsi di diversi processi. L'uso di una pipe +permette di risolvere il problema in maniera semplice ed elegante. + +Il programma ci servirà anche come esempio dell'uso di alcune delle funzioni +di manipolazione dei file descriptor, come \func{dup} e \func{dup2}, viste in +\secref{sec:file_dup} -- 2.30.2