indicare un massimo di 65535 byte (anche se Linux usa come massimo 32767 per
evitare problemi con alcuni stack bacati che usano l'aritmetica con segno
per implementare lo stack TCP); ma alcuni tipi di connessione come quelle ad
- alta velocità (sopra i 45Mbits/sec) e quelle che hanno grandi ritardi nel
+ alta velocità (sopra i 45Mbit/sec) e quelle che hanno grandi ritardi nel
cammino dei pacchetti (come i satelliti) richiedono una finestra più grande
per poter ottenere il massimo dalla trasmissione, per questo esiste questa
opzione che indica un fattore di scala da applicare al valore della finestra
attiva prevede come negoziazione che l'altro capo della connessione
riconosca esplicitamente l'opzione inserendola anche lui nel suo SYN di
risposta dell'apertura della connessione.} per la connessione corrente
- (espresso come numero di bit cui shiftare a sinistra il valore della
+ (espresso come numero di bit cui spostare a sinistra il valore della
finestra annunciata inserito nel pacchetto).
\item \textit{timestamp option}, è anche questa una nuova opzione necessaria
Come riportato da Stevens in \cite{UNP1} lo stato \texttt{TIME\_WAIT} è
probabilmente uno degli aspetti meno compresi del protocollo TCP, è infatti
-comune trovare nei newsgroup domande su come sia possibile evitare che
-un'applicazione resti in questo stato lasciando attiva una connessione ormai
-conclusa; la risposta è che non deve essere fatto, ed il motivo cercheremo di
-spiegarlo adesso.
+comune trovare domande su come sia possibile evitare che un'applicazione resti
+in questo stato lasciando attiva una connessione ormai conclusa; la risposta è
+che non deve essere fatto, ed il motivo cercheremo di spiegarlo adesso.
Come si è visto nell'esempio precedente (vedi \figref{fig:TPCel_conn_example})
\texttt{TIME\_WAIT} è lo stato finale in cui il capo di una connessione che
sulla rete; questo tempo è limitato perché ogni pacchetto IP può essere
ritrasmesso dai router un numero massimo di volte (detto \textit{hop limit}).
Il numero di ritrasmissioni consentito è indicato dal campo TTL dell'header di
-IP (per maggiori dettagli vedi \secref{sec:IP_xxx}), e viene decrementato
-ad ogni passaggio da un router; quando si annulla il pacchetto viene scartato.
-Siccome il numero è ad 8 bit il numero massimo di ``salti'' è di 255, pertanto
-anche se il TTL (da \textit{time to live}) non è propriamente un limite sul
-tempo di vita, si stima che un pacchetto IP non possa restare nella rete per
-più di MSL secondi.
+IP (per maggiori dettagli vedi \secref{sec:IP_xxx}), e viene decrementato ad
+ogni passaggio da un router; quando si annulla il pacchetto viene scartato.
+Siccome il numero è ad 8 bit il numero massimo di ``\textsl{salti}'' è di 255,
+pertanto anche se il TTL (da \textit{time to live}) non è propriamente un
+limite sul tempo di vita, si stima che un pacchetto IP non possa restare nella
+rete per più di MSL secondi.
Ogni implementazione del TCP deve scegliere un valore per la MSL (l'RFC~1122
raccomanda 2 minuti, Linux usa 30 secondi), questo comporta una durata dello
socket \param{sockfd}. Quest'ultimo (detto \textit{listening socket}) è quello
creato all'inizio e messo in ascolto con \func{listen}, e non viene toccato
dalla funzione. Se non ci sono connessioni pendenti da accettare la funzione
-mette in attesa il processo\footnote{a meno che non si sia imopstato il socket
+mette in attesa il processo\footnote{a meno che non si sia impostato il socket
per essere non bloccante (vedi \secref{sec:file_noblocking}), nel qual caso
ritorna con l'errore \errcode{EAGAIN}. Torneremo su questa modalità di
operazione in \secref{sec:xxx_sock_noblock}.} fintanto che non ne arriva
\begin{lstlisting}{}
#include <sys/types.h> /* predefined types */
#include <unistd.h> /* include unix standard library */
-#include <arpa/inet.h> /* IP addresses conversion utiliites */
+#include <arpa/inet.h> /* IP addresses conversion utililites */
#include <sys/socket.h> /* socket library */
#include <stdio.h> /* include standard I/O library */
#include <time.h>
\subsection{Le funzioni \func{getsockname} e \func{getpeername}}
\label{sec:TCPel_get_names}
-Queste due funzioni vengono usate per ottenere i dati realtivi alla socket
+Queste due funzioni vengono usate per ottenere i dati relativi alla socket
pair associata ad un certo socket; la prima è \funcd{getsockname} e
restituisce l'indirizzo locale; il suo prototipo è:
\begin{prototype}{sys/socket.h}
file che si suppone erroneamente essere esistente.
\item \errcode{EIO} \textit{Input/output error}. Errore di input/output: usato
per riportare errori hardware in lettura/scrittura su un dispositivo.
-\item \errcode{ENXIO} \textit{No such device or address}. Device inesistente:
- il sistema ha tentato di usare un dispositivo attraverso il file
- specificato, ma non lo ha trovato. Può significare che il file di
+\item \errcode{ENXIO} \textit{No such device or address}. Dispositivo
+ inesistente: il sistema ha tentato di usare un dispositivo attraverso il
+ file specificato, ma non lo ha trovato. Può significare che il file di
dispositivo non è corretto, che il modulo relativo non è stato caricato nel
kernel, o che il dispositivo è fisicamente assente o non funzionante.
\item \errcode{ENOEXEC} \textit{Invalid executable file format}. Il file non ha
processo figlio. Viene rilevato dalle funzioni per la gestione dei processi
figli.
%\item \errcode{EPROCLIM} \textit{}. Il limite dell'utente per nuovi processi
-% sarà ecceduto alla prossima \func{fork}. (non credo esista in linux)
+% sarà ecceduto alla prossima \func{fork}. (non credo esista in Linux)
\end{description}
comando o opzione o che, in caso di oggetti specifici (file descriptor o
altro) non è in grado di supportare i parametri richiesti.
\item \errcode{EILSEQ} \textit{Illegal byte sequence}. Nella decodifica di un
- carattere multibyte si è avuta una sequenza errata o incompleta o si è
+ carattere esteso si è avuta una sequenza errata o incompleta o si è
specificato un valore non valido.
\end{description}
\textsl{montaggio} del \textit{filesystem}.
% (approfondiremo tutto ciò in \secref{sec:file_arch_func}).
-In questa sezione faremo una panormamica generica su come il sistema presenta
+In questa sezione faremo una panoramica generica su come il sistema presenta
i file ai processi, trattando l'organizzazione di file e directory, i tipi di
file ed introducendo le interfacce disponibili e le loro caratteristiche.
una serie di nomi separati da una \file{/}.
All'avvio del sistema, completata la fase di inizializzazione, il kernel
-riceve dal boot loader l'indicazione di quale dispositivo contiene il
+riceve dal bootloader 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 \file{/}); tutti gli ulteriori filesystem
che possono essere su altri dispositivi dovranno poi essere inseriti
un file che identifica una periferica ad accesso a caratteri \\
\textit{block device} & \textsl{dispositivo a blocchi} &
un file che identifica una periferica ad accesso a blocchi \\
- \textit{fifo} & \textsl{``coda''} &
+ \textit{fifo} & ``\textsl{coda}'' &
un file speciale che identifica una linea di comunicazione software
unidirezionale (vedi \secref{sec:ipc_named_pipe}).\\
- \textit{socket}\index{socket} & \textsl{``presa''} &
+ \textit{socket}\index{socket} & ``\textsl{presa}''&
un file speciale che identifica una linea di comunicazione software
bidirezionale (vedi \capref{cha:socket_intro}) \\
\hline
flusso continuo di byte. 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.\footnote{questo vale
- anche per i dispositivi a blocchi: la strutturazione dell'I/O in blocchi di
- dimensione fissa avviene solo all'interno del kernel, ed è completamente
- trasparente all'utente. Inoltre talvolta si parla di \textsl{accesso
- diretto} riferendosi alla capacità, che non ha niente a che fare con tutto
- ciò, di effettuare, attraverso degli appositi file di
+il cosiddetto ``\textsl{accesso diretto}'' come nel caso del
+VMS.\footnote{questo vale anche per i dispositivi a blocchi: la strutturazione
+ dell'I/O in blocchi di dimensione fissa avviene solo all'interno del kernel,
+ ed è completamente trasparente all'utente. Inoltre talvolta si parla di
+ \textsl{accesso diretto} riferendosi alla capacità, che non ha niente a che
+ fare con tutto ciò, di effettuare, attraverso degli appositi file di
dispositivo\index{file!di dispositivo}, operazioni di I/O direttamente sui
dischi senza passare attraverso un filesystem (il cosiddetto \textit{raw
access}, introdotto coi kernel della serie 2.4.x).}
disco e che identifica un singolo oggetto del VFS sia esso un file ordinario,
una directory, un link simbolico, una FIFO, un file di
dispositivo\index{file!di dispositivo}, o una qualsiasi altra cosa che possa
-essere rappresentata dal VFS (i tipi di ``file'' riportati in
+essere rappresentata dal VFS (i tipi di file riportati in
\tabref{tab:file_file_types}). A ciascuno di essi è associata pure una
struttura che sta in memoria, e che, oltre alle informazioni sullo specifico
file, contiene anche il riferimento alle funzioni (i \textsl{metodi} del VFS)
riguarda l'aspetto della scrittura dei dati sul file.
I caratteri che vengono scritti su di uno stream normalmente vengono
-accumulati in un buffer e poi trasmessi in blocco\footnote{qiesta operazione
+accumulati in un buffer e poi trasmessi in blocco\footnote{questa operazione
viene usualmente chiamata \textsl{scaricamento} dei dati, dal termine
inglese \textit{flush}.} tutte le volte che il buffer viene riempito, in
maniera asincrona rispetto alla scrittura. Un comportamento analogo avviene
dell'input/output interattivo, bisognerà tenere presente le caratteristiche
delle operazioni di scaricamento dei dati, poiché non è detto che ad una
scrittura sullo stream corrisponda una immediata scrittura sul dispositivo (la
-cosa è particolaemente evidente quando con le operazioni di input/output su
+cosa è particolarmente evidente quando con le operazioni di input/output su
terminale).
Per rispondere ad esigenze diverse, lo standard definisce tre distinte
esattamente le stesse operazioni delle loro equivalenti, evitando però il lock
implicito dello stream (vedi \secref{sec:file_stream_thread}). Come per le
altre forma di I/O, dette funzioni hanno lo stesso nome della loro analoga
-normale, con l'aggiuta dell'estensione \code{\_unlocked}.
+normale, con l'aggiunta dell'estensione \code{\_unlocked}.
Come abbiamo visto, le funzioni di lettura per l'input/output di linea
previste dallo standard ANSI C presentano svariati inconvenienti. Benché
In corrispondenza alla famiglia di funzioni \func{printf} che si usano per
l'output formattato, l'input formattato viene eseguito con le funzioni della
famiglia \func{scanf}; fra queste le tre più importanti sono \funcd{scanf},
-\funcd{fscanf} e \funcd{sscanf}, i cui proprotipi sono:
+\funcd{fscanf} e \funcd{sscanf}, i cui prototipi sono:
\begin{functions}
\headdecl{stdio.h} \funcdecl{int scanf(const char *format, ...)} Esegue una
scansione di \file{stdin} cercando una corrispondenza di quanto letto con il
conversione delle stringhe; se invece il formato è più complesso diventa più
facile utilizzare uno strumento come \cmd{flex}\footnote{il programma
\cmd{flex}, è una implementazione libera di \cmd{lex} un generatore di
- analizzatori lessicali, per i dettagli si può fare riferimento al manuale
+ analizzatori lessicali. Per i dettagli si può fare riferimento al manuale
\cite{flex}.} per generare un analizzatore lessicale o il
\cmd{bison}\footnote{il programma \cmd{bison} è un clone del generatore di
parser \cmd{yacc}, maggiori dettagli possono essere trovati nel relativo
file con un nome univoco e la funzione \func{link} per verificarne
l'esistenza (vedi \secref{sec:ipc_file_lock}).}
-\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[3]{\textit{Denial of Service}\index{DoS}, 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
Una parte del kernel, lo \textit{scheduler}\index{scheduler}, si occupa di
stabilire, ad intervalli fissi e sulla base di un opportuno calcolo delle
-priorità, quale ``processo'' deve essere posto in esecuzione (il cosiddetto
-\textit{preemptive scheduling}\index{preemptive scheduling}). Questo verrà
-comunque eseguito in modalità protetta; quando necessario il processo potrà
-accedere alle risorse hardware soltanto attraverso delle opportune chiamate al
-sistema che restituiranno il controllo al kernel.
+priorità, quale ``\textsl{processo}'' deve essere posto in esecuzione (il
+cosiddetto \textit{preemptive scheduling}\index{preemptive scheduling}).
+Questo verrà comunque eseguito in modalità protetta; quando necessario il
+processo potrà accedere alle risorse hardware soltanto attraverso delle
+opportune chiamate al sistema che restituiranno il controllo al kernel.
La memoria viene sempre gestita dal kernel attraverso il meccanismo della
\textsl{memoria virtuale}\index{memoria virtuale}, che consente di assegnare a
-ciascun processo uno spazio di indirizzi ``virtuale'' (vedi
+ciascun processo uno spazio di indirizzi ``\textsl{virtuale}'' (vedi
\secref{sec:proc_memory}) che il kernel stesso, con l'ausilio della unità di
gestione della memoria, si incaricherà di rimappare automaticamente sulla
memoria disponibile, salvando su disco quando necessario (nella cosiddetta
completamente soppiantate dalle \acr{glibc}, le \textit{uClib} pur non
essendo complete come le \acr{glibc}, restano invece molto diffuse nel mondo
embedded per le loro di dimensioni ridotte (e soprattutto la possibilità di
- togliere le parti non necessearie), e pertanto costituiscono un valido
+ togliere le parti non necessarie), e pertanto costituiscono un valido
rimpiazzo delle \acr{glibc} in tutti quei sistemi specializzati che
richiedono una minima occupazione di memoria.} si dovrebbe usare il nome
GNU/Linux (piuttosto che soltanto Linux) in quanto una parte essenziale del
POSIX.2 & 1003.2 & 9945-2& Comandi \\
POSIX.3 & 2003 &TR13210& Metodi di test \\
POSIX.4 & 1003.1b & --- & Estensioni real-time \\
- POSIX.4a& 1003.1c & --- & Threads \\
+ POSIX.4a& 1003.1c & --- & Thread \\
POSIX.4b& 1003.1d &9945-1& Ulteriori estensioni real-time \\
POSIX.5 & 1003.5 & 14519& Interfaccia per il linguaggio ADA \\
POSIX.6 & 1003.2c,1e& 9945-2& Sicurezza \\
POSIX.8 & 1003.1f& 9945-1& Accesso ai file via rete \\
- POSIX.9 & 1003.9 & --- & Intercaccia per il Fortran-77 \\
- POSIX.12& 1003.1g& 9945-1& Sockets \\
+ POSIX.9 & 1003.9 & --- & Interfaccia per il Fortran-77 \\
+ POSIX.12& 1003.1g& 9945-1& Socket \\
\hline
\end{tabular}
\caption{Elenco dei vari standard POSIX e relative denominazioni.}
del nome \textit{Unix 98}, usato spesso anche per riferirsi allo standard.
-\subsection{Lo ``standard'' BSD}
+\subsection{Lo ``\textsl{standard}'' BSD}
\label{sec:intro_bsd}
Lo sviluppo di BSD iniziò quando la fine della collaborazione fra l'Università
standard ISO C, POSIX.1, POSIX.2, and X/Open.
\item[\macro{\_XOPEN\_SOURCE}] definendo questa macro si attivano le
funzionalità descritte nella \textit{X/Open Portability Guide}. Anche queste
- sono un soprainsieme di quelle definite in POSIX.1 e POSIX.2 ed in effetti
+ sono un sovrainsieme di quelle definite in POSIX.1 e POSIX.2 ed in effetti
sia \macro{\_POSIX\_SOURCE} che \macro{\_POSIX\_C\_SOURCE} vengono
automaticamente definite. Sono incluse anche ulteriori funzionalità
disponibili in BSD e SVID. Se il valore della macro è posto a 500 questo
processo alla volta (nel qual caso basta usare due fifo, una per leggere ed
una per scrivere), le cose diventano invece molto più complesse quando si
vuole effettuare una comunicazione fra il server ed un numero imprecisato di
-client; se il primo infatti può ricevere le richieste attraverso una fifo```\textsl{nota}'', per le risposte non si può fare altrettanto, dato che, per
+client; se il primo infatti può ricevere le richieste attraverso una fifo
+``\textsl{nota}'', per le risposte non si può fare altrettanto, dato che, per
la struttura sequenziale delle fifo, i client dovrebbero sapere, prima di
leggerli, quando i dati inviati sono destinati a loro.
Un esempio classico di uso della memoria condivisa è quello del
``\textit{monitor}'', in cui essa viene per scambiare informazioni fra un
-processo ``server'' che vi scrive dei dati di interesse generale che ha
-ottenuto, e tutti i processi ``client'' interessati agli stessi dati che così
+processo server che vi scrive dei dati di interesse generale che ha
+ottenuto, e tutti i processi client interessati agli stessi dati che così
possono leggerli in maniera completamente asincrona. Con questo schema di
-funzionamento da una parte si evita che ciascun processo ``client'' debba
+funzionamento da una parte si evita che ciascun processo client debba
compiere l'operazione, potenzialmente onerosa, di ricavare e trattare i dati,
-e dall'altra si evita al processo ``server'' di dover gestire l'invio a tutti
+e dall'altra si evita al processo server di dover gestire l'invio a tutti
i client di tutti i dati (non potendo il server sapere quali di essi servono
effettivamente al singolo client).
-Nel nostro caso implementeremo un ``monitor'' di una directory: un processo si
-incaricherà di tenere sotto controllo alcuni parametri relativi ad una
-directory (il numero dei file contenuti, la dimensione totale, ecc.) che
+Nel nostro caso implementeremo un ``\textsl{monitor}'' di una directory: un
+processo si incaricherà di tenere sotto controllo alcuni parametri relativi ad
+una directory (il numero dei file contenuti, la dimensione totale, ecc.) che
saranno salvati in un segmento di memoria condivisa cui altri processi
potranno accedere per ricavare la parte di informazione che interessa.
\item è stato introdotto un nuovo campo \textit{flow label}, che viene usato,
insieme al campo \textit{priority} (che recupera i bit di precedenza del
campo \textit{type of service}) per implementare la gestione di una
- ``qualità di servizio'' (vedi \secref{sec:IP_ipv6_qos}) che permette di
- identificare i pacchetti appartenenti a un ``flusso'' di dati per i quali si
- può provvedere un trattamento speciale.
+ ``\textsl{qualità di servizio}'' (vedi \secref{sec:IP_ipv6_qos}) che
+ permette di identificare i pacchetti appartenenti a un ``\textsl{flusso}''
+ di dati per i quali si può provvedere un trattamento speciale.
\end{itemize}
\textsl{flag} bit di frammentazione, uno indica se un
pacchetto è frammentato, un'altro se ci sono ulteriori frammenti, e
un'altro se il pacchetto non può essere frammentato. \\
- \textit{fragmentation offset} & 13 bit& \textsl{offset di frammento},
+ \textit{fragmentation offset} & 13 bit & \textsl{offset di frammento},
indica la posizione del frammento rispetto al pacchetto originale\\
\textit{time to live} & 16 bit & \textsl{tempo di vita},
ha lo stesso significato di
Gli indirizzi \textit{anycast} sono indirizzi che vengono assegnati ad un
gruppo di interfacce: un pacchetto indirizzato a questo tipo di indirizzo
-viene inviato al componente del gruppo più ``vicino'' secondo la distanza di
+viene inviato al componente del gruppo più ``\textsl{vicino}'' secondo la distanza di
instradamento calcolata dai router.
Questi indirizzi sono allocati nello stesso spazio degli indirizzi unicast,
\label{sec:net_cliserv}
La differenza principale fra un'applicazione di rete e un programma normale è
-che quest'ultima per definizione concerne la comunicazione fra ``processi''
+che quest'ultima per definizione concerne la comunicazione fra processi
diversi (che in generale non girano neanche sulla stessa macchina). Questo già
-prefigura un cambiamento completo rispetto all'ottica del ``programma''
-monolitico all'interno del quale vengono eseguite tutte le istruzioni, e
-presuppone un sistema operativo ``multitasking'' in grado di eseguire processi
+prefigura un cambiamento completo rispetto all'ottica del programma monolitico
+all'interno del quale vengono eseguite tutte le istruzioni, e chiaramente
+presuppone un sistema operativo multitasking in grado di eseguire processi
diversi.
Un concetto fondamentale su cui si basa la programmazione di rete sotto Linux
in cui un client può scrivere su uno stesso socket\index{socket} pacchetti
destinati a server diversi, o un server ricevere su un socket\index{socket}
pacchetti provenienti da client diversi. Il modo più semplice di immaginarsi
-il funzionamento di UDP è quello della radio, in cui si può ``trasmettere a''
-e ``ricevere da'' più stazioni usando la stessa frequenza.
+il funzionamento di UDP è quello della radio, in cui si può
+``\textsl{trasmettere a}'' e ``\textsl{ricevere da}'' più stazioni usando la
+stessa frequenza.
Nonostante gli evidenti svantaggi comportati dall'inaffidabilità UDP ha il
grande pregio della velocità che in certi casi è essenziale; inoltre si presta
effettuata.
Caratteristica fondamentale di TCP è l'affidabilità; quando i dati vengono
-inviati attraverso una connessione ne viene richiesto un ``ricevuto''
+inviati attraverso una connessione ne viene richiesto un ``\textsl{ricevuto}''
(il cosiddetto \textit{acknowlegment}), se questo non arriva essi verranno
-ritrasmessi per un determinato numero di tentativi, intervallati da un
-periodo di tempo crescente, fino a che sarà considerata fallita o caduta la
+ritrasmessi per un determinato numero di tentativi, intervallati da un periodo
+di tempo crescente, fino a che sarà considerata fallita o caduta la
connessione (e generato un errore di \textit{time-out}), dopo un periodo di
-tempo che dipende dall'implementazione e che può variare far i
-quattro e i dieci minuti.
+tempo che dipende dall'implementazione e che può variare far i quattro e i
+dieci minuti.
Inoltre per tenere conto delle diverse condizioni in cui può trovarsi la linea
di comunicazione TCP comprende anche un algoritmo di calcolo dinamico del
entrambe), operare. Esso può prendere i valori riportati in
\tabref{tab:sess_tcflush_queue}, nel caso si specifichi la coda di ingresso
cancellerà i dati ricevuti ma non ancora letti, nel caso si specifichi la coda
-di uscita cancellerài dati scritti ma non ancora trasmessi.
+di uscita cancellerà i dati scritti ma non ancora trasmessi.
\begin{table}[htb]
\footnotesize
\funcdecl{int tcflow(int fd, int action)}
- Sospende e rivvia il flusso dei dati sul terminale.
+ Sospende e riavvia il flusso dei dati sul terminale.
\bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di
errore, nel qual caso \var{errno} assumerà i valori \errval{EBADF} o
\item[\const{SIGTERM}] Il nome sta per \textit{terminate}. È un segnale
generico usato per causare la conclusione di un programma. Al contrario di
\const{SIGKILL} può essere intercettato, ignorato, bloccato. In genere lo si
- usa per chiedere in maniera ``educata'' ad un processo di concludersi.
+ usa per chiedere in maniera ``\textsl{educata}'' ad un processo di
+ concludersi.
\item[\const{SIGINT}] Il nome sta per \textit{interrupt}. È il segnale di
interruzione per il programma. È quello che viene generato di default dal
comando \cmd{kill} o dall'invio sul terminale del carattere di controllo
In alcuni casi però alcune system call (che per questo motivo vengono chiamate
\textsl{lente}) possono bloccarsi indefinitamente. In questo caso non si può
-attendere la conclusione della sistem call, perché questo renderebbe
+attendere la conclusione della system call, perché questo renderebbe
impossibile una risposta pronta al segnale, per cui il gestore viene
eseguito prima che la system call sia ritornata. Un elenco dei casi in cui si
presenta questa situazione è il seguente:
Come accennato in \secref{sec:sig_types}, un segnale può essere generato
direttamente da un processo attraverso una opportuna system call. Le funzioni
-che si usano di solito per invare un segnale generico sono due, \func{raise} e
+che si usano di solito per inviare un segnale generico sono due, \func{raise} e
\func{kill}.
La prima funzione è \funcd{raise}, che è definita dallo standard ANSI C, e
terminazione del processo, cosa che viene eseguita nel ciclo in
(\texttt{\small 15-21}). Il ciclo è necessario a causa di una caratteristica
fondamentale della gestione dei segnali: abbiamo già accennato come fra la
-generazione di un segnale e l'esecuzione del gestore possa passare un
-certo lasso di tempo e niente ci assicura che il gestore venga eseguito
-prima della generazione di ulteriori segnali dello stesso tipo. In questo caso
-normalmente i segnali segnali successivi vengono ``fusi'' col primo ed al
+generazione di un segnale e l'esecuzione del gestore possa passare un certo
+lasso di tempo e niente ci assicura che il gestore venga eseguito prima della
+generazione di ulteriori segnali dello stesso tipo. In questo caso normalmente
+i segnali segnali successivi vengono ``\textsl{fusi}'' col primo ed al
processo ne viene recapitato soltanto uno.
Questo può essere un caso comune proprio con \const{SIGCHLD}, qualora capiti
maggiori dettagli riguardo l'errore (come il tipo di errore aritmetico, di
istruzione illecita o di violazione di memoria) mentre alcuni segnali di
controllo (\const{SIGCHLD}, \const{SIGTRAP} e \const{SIGPOLL}) forniscono
-altre informazioni speecifiche. In tutti i casi il valore del campo è
+altre informazioni specifiche. In tutti i casi il valore del campo è
riportato attraverso delle costanti (le cui definizioni si trovano
\file{bits/siginfo.h}) il cui elenco dettagliato è disponibile nella pagina di
manuale di di \func{sigaction}.
real-time.
Si tenga presente che questi nuovi segnali non sono associati a nessun evento
-sepcifico (a meno di non utilizzarli, come vedremo in
+specifico (a meno di non utilizzarli, come vedremo in
\secref{sec:file_asyncronous_io}, per l'I/O asincrono) e devono essere inviati
esplicitamente. Tutti i segnali real-time restituiscono al gestore, oltre ai
campi \var{si\_pid} e \var{si\_uid} di \struct{siginfo\_t} una struttura
\bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di
errore, nel qual caso \var{errno} assumerà uno dei valori:
\begin{errlist}
- \item[\errcode{EAGAIN}] La coda è esarita, ci sono già \const{SIGQUEUE\_MAX}
+ \item[\errcode{EAGAIN}] La coda è esaurita, ci sono già \const{SIGQUEUE\_MAX}
segnali in attesa si consegna.
\item[\errcode{EPERM}] Non si hanno privilegi appropriati per inviare il
segnale al processo specificato.
\func{sigwait}, ai quali si aggiunge, per \func{sigtimedwait}:
\begin{errlist}
\item[\errcode{EAGAIN}] Si è superato il timeout senza che un segnale atteso
- fosse emmesso.
+ fosse emesso.
\end{errlist}
}
\end{functions}
La seconda è identica alla prima ma in più permette di specificare un timeout,
scaduto il quale ritornerà con un errore. Se si specifica un puntatore nullo
il comportamento sarà identico a \func{sigwaitinfo}, se si specifica un tempo
-di timeout nullo, e non ci sono sengali pendenti la funzione ritornerà
+di timeout nullo, e non ci sono segnali pendenti la funzione ritornerà
immediatamente; in questo modo si può eliminare un segnale dalla coda senza
dover essere bloccati qualora esso non sia presente.
all'indirizzo specificato dalla linea di comando (a cui si è aggiunta una
elementare gestione delle opzioni non riportata in figura).
-Completata la connessione, al ritrno fiììdi \func{connect} è ritornata, la
-funzione \code{ClientEcho}, riportata in
-\figref{fig:TCPsimpl_client_echo_sub}, si preoccupa di gestire la
-comunicazione, leggendo una riga alla volta dallo \file{stdin}, scrivendola
-sul socket e ristampando su \file{stdout} quanto ricevuto in risposta dal
-server.
+Completata la connessione, al ritorno di \func{connect}, la funzione
+\code{ClientEcho}, riportata in \figref{fig:TCPsimpl_client_echo_sub}, si
+preoccupa di gestire la comunicazione, leggendo una riga alla volta dallo
+\file{stdin}, scrivendola sul socket e ristampando su \file{stdout} quanto
+ricevuto in risposta dal server.
\begin{figure}[!htb]
\footnotesize
con un solo partner come per una telefonata; altri casi possono prevedere una
comunicazione come per lettera, in cui si scrive l'indirizzo su ogni
pacchetto, altri ancora una comunicazione \textit{broadcast} come per la
-radio, in cui i pacchetti vengono emessi su appositi ``canali'' dove chiunque
-si collega possa riceverli.
+radio, in cui i pacchetti vengono emessi su appositi ``\textsl{canali}'' dove
+chiunque si collega possa riceverli.
É chiaro che ciascuno di questi stili comporta una modalità diversa di gestire
la comunicazione, ad esempio se è inaffidabile occorrerà essere in grado di
\funcd{socket}; questa restituisce un \textit{file descriptor}\footnote{del
tutto analogo a quelli che si ottengono per i file di dati e le pipe,
descritti in \secref{sec:file_fd}.} che serve come riferimento al socket; il
-suo protototipo è:
+suo prototipo è:
\begin{prototype}{sys/socket.h}{int socket(int domain, int type, int protocol)}
Apre un socket.
\bodydesc{Tutte queste le funzioni non generano codice di errore.}
\end{functions}
-La prima funcione, \func{inet\_addr}, restituisce l'indirizzo a 32 bit in
+La prima funzione, \func{inet\_addr}, restituisce l'indirizzo a 32 bit in
network order (del tipo \type{in\_addr\_t}) a partire dalla stringa passata
-nellargomento \param{strptr}. In caso di errore (quando la stringa non esprime
+nell'argomento \param{strptr}. In caso di errore (quando la stringa non esprime
un indirizzo valido) restituisce invece il valore \const{INADDR\_NONE} che
tipicamente sono trentadue bit a uno. Questo però comporta che la stringa
\texttt{255.255.255.255}, che pure è un indirizzo valido, non può essere usata
\struct{in\_addr} (si veda \secref{fig:sock_sa_ipv4_struct}) situata
all'indirizzo dato dall'argomento \param{dest} (è espressa in questa forma in
modo da poterla usare direttamente con il puntatore usato per passare la
-struttura degli indirizzi). La funzione restituesce 0 in caso di successo e 1
+struttura degli indirizzi). La funzione restituisce 0 in caso di successo e 1
in caso di fallimento. Se usata con \param{dest} inizializzato a \val{NULL}
effettua la validazione dell'indirizzo.
un indirizzo valido, e negativo se \param{af} specifica una famiglia di
indirizzi non valida.
-La sedonda funzione è \funcd{inet\_ntop} che converte un indirizzo in una
+La seconda funzione è \funcd{inet\_ntop} che converte un indirizzo in una
stringa; il suo prototipo è:
\begin{prototype}{sys/socket.h}
{char *inet\_ntop(int af, const void *addr\_ptr, char *dest, size\_t len)}
\bodydesc{La funzione restituisce un puntatore non nullo alla stringa
convertita in caso di successo e \val{NULL} in caso di fallimento, nel
- qual caso \var{errno} assume i valor:
+ qual caso \var{errno} assume i valori:
\begin{errlist}
\item[\errcode{ENOSPC}] le dimensioni della stringa con la conversione
dell'indirizzo eccedono la lunghezza specificata da \param{len}.
int tm_yday; /* day in the year */
int tm_isdst; /* daylight saving time */
long int tm_gmtoff; /* Seconds east of UTC. */
- cost char *tm_zone; /* Timezone abbreviation. */
+ const char *tm_zone; /* Timezone abbreviation. */
};
\end{lstlisting}
\end{minipage}
Benché la funzione \func{asctime} fornisca la modalità più immediata per
stampare un tempo o una data, la flessibilità non fa parte delle sue
caratteristiche; quando si vuole poter stampare solo una parte (l'ora, o il
-gionrno) di un tempo si può ricorrere alla più sofisticata \funcd{strftime},
+giorno) di un tempo si può ricorrere alla più sofisticata \funcd{strftime},
il cui prototipo è:
\begin{prototype}{time.h}
{size\_t strftime(char *s, size\_t max, const char *format,
\param{format}.
\bodydesc{La funzione ritorna il numero di caratteri stampati in \param{s},
- altrimenti restuisce 0.}
+ altrimenti restituisce 0.}
\end{prototype}
La funzione converte opportunamente il tempo \param{tm} in una stringa di
le \acr{glibc} provvedono tutte le estensioni introdotte da POSIX.2 per il
comando \cmd{date}, i valori introdotti da SVID3 e ulteriori estensioni GNU;
l'elenco completo dei possibili valori è riportato nella pagina di manuale
- della funzione.} dei possibili valori che esso può assumere sono ripotati in
+ della funzione.} dei possibili valori che esso può assumere sono riportati in
\tabref{tab:sys_strftime_format}. La funzione tiene conto anche della presenza
di una localizzazione per stampare in maniera adeguata i vari nomi.