\section{L'uso di \texttt{make} per l'automazione della compilazione}
+\label{sec:build_make}
Il comando \texttt{make} serve per automatizzare il processo di costruzione di
un programma ed effettuare una compilazione intelligente di tutti i file
\subsection {Introduzione a \texttt{make}}
+\label{sec:make_intro}
Con \texttt{make} si possono definire i simboli del preprocessore C che
consentono la compilazione condizionale dei programmi (anche in Fortran); è
di \texttt{OBJ}.
-\section{Cuncurrent Version System -- CVS}
-
-Il programma CVS è un sistema di archiviazione dei programmi che consente di
-tenere traccia di tutte le modifiche e di condividere un archivio comune per
-progetti portati avanti da diverse persone.
-
-\subsection{Introduzione}
-CVS è basato sul concetto di repositorio, un archivio in cui vengono riposti
-e da cui vengono presi i sorgenti dei programmi. L'archivio tiene traccia delle
-diverse versioni registrate; i programmatori inviano le modifiche usando una
-copia locale che hanno nella loro directory di lavoro.
-
-CVS può gestire più di un progetto, esso organizza i progetti in
-\textsl{moduli} identificati dal nome della directory in cui sono messi i file
-relativi, ad esempio:
-\small
+\section{Source Control Management}
+\label{sec:build_scm}
+
+Uno dei problemi più comuni che si hanno nella programmazione è quella di
+poter disporre di un sistema che consenta di tenere conto del lavoro
+effettuato, di tracciare l'evoluzione del codice, e, soprattutto nel caso di
+progetti portati avanti da più persone, consentire un accesso opportunamente
+coordinato fra i vari partecipanti alla base comune dei sorgenti dello
+sviluppo.
+
+I programmi che servono a questo scopo vanno sotto il nome comune di SCM
+(\textit{Source Control Manager}), e ne esistono di diversi tipi con diverse
+filosofie progettuali, in particolare nelle modalità con cui gestiscono
+l'accesso alla base di codice comune da parte dei singoli programmatori che vi
+accedono.
+
+Fra questi uno dei più usati, nonostante la sua architettura sia considerata
+superata, è Subversion, un sistema di archiviazione centralizzata del codice
+che consente di tenere traccia di tutte le modifiche e di condividere un
+archivio comune per progetti portati avanti da diverse persone.
+
+\subsection{Introduzione a Subversion}
+\label{sec:build_subversion}
+
+Subversion è basato sul concetto di \textit{repository}, un archivio
+centralizzato in cui vengono riposti e da cui vengono presi i sorgenti dei
+programmi. L'archivio tiene traccia delle diverse versioni registrate; i
+programmatori inviano le modifiche usando una copia locale che hanno nella
+loro directory di lavoro.
+
+Subversion può gestire più di un progetto all'interno di un singolo server,
+ciascuno dei quali viene associato ad un \textit{repository} distinto, ma si
+possono anche creare sotto-progetti suddividendo un \textit{repository} in
+diverse directory; ma ciascun progetto avrà meccanismi di controllo (ad
+esempio quelli che consentono di inviare email all'inserimento di nuovo
+codice) comuni.
+
+Una delle caratteristiche che contraddistinguono Subversion dal suo
+predecessore CVS è quella di essere gestibile in maniera molto flessibile
+l'accesso al repository, che può avvenire sia in maniera diretta facendo
+riferimento alla directory in cui questo è stato installato che via rete,
+tramite diversi protocolli. L'accesso più comune è fatto direttamente via
+HTTP, utilizzando opportune estensioni del protocollo DAV, ma è possibile
+passare attraverso SSH o fornire un servizio di rete dedicato.\footnote{esiste
+ all'uopo il programma \texttt{svnserve}, ma il suo uso è sconsigliato per le
+ scarse prestazioni e le difficoltà riscontrate a gestire accessi di utenti
+ diversi; la modalità di accesso preferita resta quella tramite le estensioni
+ al protocollo DAV.}
+
+In generale è comunque necessario preoccuparsi delle modalità di accesso al
+codice soltanto in fase di primo accesso al \textit{repository}, che occorrerà
+identificare o con il pathname alla directory dove questo si trova o con una
+opportuna URL (con il comune accesso via web del tutto analoga a quella che si
+usa in un browser), dopo di che detto indirizzo sarà salvato nella propria
+copia locale dei dati ed il riferimento diventerà implicito.
+
+Il programma prevede infatti che in ogni directory che si è ottenuta come
+copia locale sia presente una directory \texttt{.svn} contenente tutti i dati
+necessari al programma. Inoltre il programma usa la directory
+\texttt{.subversion} nella home dell'utente per mantenere le configurazioni
+generali del client e le eventuali informazioni di autenticazione.
+
+Tutte le operazioni di lavoro sul \textit{repository} vengono effettuate lato
+client tramite il comando \texttt{svn} che vedremo in
+sez.~\ref{sec:build_subversion} ma la creazione e la inizializzazione dello
+stesso (così come la gestione lato server) devono essere fatte tramite il
+comando \texttt{svnadmin} eseguito sulla macchina che lo ospita. In generale
+infatti il comando \texttt{svn} richiede che si faccia riferimento ad un
+\textit{repository} (al limite anche vuoto) esistente e questo deve essere
+opportunamente creato.
+
+Il comando \texttt{svnadmin} utilizza una sintassi che richiede sempre
+l'ulteriore specificazione di un sotto-comando, seguito da eventuali altri
+argomenti. L'inizializzazione di un \textit{repository} (che sarà creato
+sempre vuoto) viene eseguita con il comando:
\begin{verbatim}
-[piccardi@pcpamela ~]$ ls /usr/local/cvsroot/
-CVSROOT adidsp geometry muonacq pamela
+svnadmin create /path/to/repository
\end{verbatim}
-\normalsize %$
-in questo caso si hanno i moduli \texttt{adidsp geometry muonacq pamela}; un
-utente potrà recuperare tutti i file relativi al modulo \texttt{pamela} che
-andaranno nella directory \texttt{pamela}; è anche possibile gestire una
-gerarchia di moduli, inseriti in un albero di directory.
-
-CVS ha una directory base dove tiene gli archivi (che nel è appunto
-\texttt{/usr/local/cvsroot}) e i vari file amministrativi; ogni progetto deve
-fare riferimento ad essa; in un progetto attivo essa viene memorizzata nei
-file amministrativi locali del progetto (ad esempio per un utente che ha il
-progetto \texttt{muonacq} nella sua home directory sarà in
-\texttt{\tild/muonacq/CVS}) e non è necessario specificarla; in generale essa
-viene tenuta dalla variabile di shell \texttt{CVSROOT} (inizializzata allo
-startup), o specificata direttamente dall'utente con l'apposita opzione
-\texttt{-d} (ex. \texttt{cvs -d /usr/local/cvsroot comando opzioni}).
-
-Normalmente l'archivio si tiene su una macchina remota e vi si accede via
-rete. Per repositori esterni esistono varie modalità di accesso, la via più
-semplice è quella dell'uso di \texttt{ssh} come rimpiazzo di \texttt{rsh} per
-l'accesso esterno; in tal caso la directory del repositorio si può accedere
-con la sintassi: \small
+dove \texttt{/path/to/repository} è la directory dove verranno creati e
+mantenuti tutti i file, una volta creato il \textit{repository} si potrà
+iniziare ad utilizzarlo ed inserirvi i contenuti con il comando \texttt{svn}.
+
+Non essendo questo un testo di amministrazione di sistema non tratteremo qui i
+dettagli della configurazione del server per l'accesso via rete al
+\textit{repository}, per i quali si rimanda alla documentazione del progetto
+ed alla documentazione sistemistica scritta per Truelite
+Srl.\footnote{rispettivamente disponibili su \url{svn.tigris.org} e
+ \url{labs.truelite.it/truedoc}.}
+
+\subsection{Utilizzo di \texttt{svn}}
+\label{sec:build_subversion}
+
+Una volta che si abbia a disposizione un \textit{repository} si potrà creare
+un nuovo progetto sottoposto a controllo di versione importando al suo interno
+i dati disponibili. In genere è pratica comune suddividere il contenuto di un
+repository in tre directory secondo il seguente schema:
+\begin{basedescript}{\desclabelwidth{2.7cm}\desclabelstyle{\nextlinelabel}}
+\item[\texttt{trunk}] contiene la versione corrente i sviluppo, su cui vengono
+ effettuate normalmente le modifiche e gli aggiornamenti;
+\item[\texttt{tags}] contiene le diverse versioni \textsl{fotografate} ad un
+ certo istante del processo di sviluppo, ad esempio in occasione del rilascio
+ di una versione stabile, così che sia possibile identificarle facilmente;
+\item[\texttt{branches}] contiene \textsl{rami} alternativi di sviluppo, ad
+ esempio quello delle correzioni eseguite ad una versione stabile, che
+ vengono portati avanti in maniera indipendente dalla versione principale.
+\end{basedescript}
+
+Questa suddivisione consente di sfruttare la capacità di Subversion di creare
+senza spesa copie diverse del proprio contenuto, pertanto in genere si pone il
+proprio progetto di sviluppo sotto \texttt{trunk}, e si copia quest'ultima in
+occasione delle varie versioni di rilascio in altrettante sottocartelle di
+\texttt{tags} e qualora si voglia aprire un ramo alternativo di sviluppo
+basterà copiarsi il punto di partenza del ramo sotto \texttt{branches} e
+iniziare ad eseguire le modifiche su di esso.
+
+Le operazioni di gestione di un progetto con Subversion vengono eseguite con
+il comando \texttt{svn}, che analogamente al precedente \texttt{svnadmin}
+utilizza una sintassi basata sulla specificazione degli opportuni
+sotto-comandi. Si sono riportati quelli più importanti in
+tab.~\ref{tab:svn_mainsubcommands}.
+
+\begin{table}[htb]
+ \centering
+ \footnotesize
+ \begin{tabular}[c]{|l|l|p{8cm}|}
+ \hline
+ \multicolumn{2}{|c|}{\textbf{Sotto-comando}}& \textbf{Significato} \\
+ \hline
+ \hline
+ \texttt{import} & -- & Importa i file della directory corrente sul
+ \textit{repository}.\\
+ \texttt{checkout}&\texttt{co}& Scarica una versione del progetto dal
+ \textit{repository}.\\
+ \texttt{commit} &\texttt{ci}& Invia le modifiche effettuate localmente al
+ \textit{repository}.\\
+ \texttt{add} & -- & Richiede l'aggiunta un file o una directory
+ al \textit{repository}.\\
+ \texttt{remove} &\texttt{rm}& Richiede la rimozione un file o una
+ directory dal \textit{repository}.\\
+ \texttt{copy} &\texttt{cp}& Richiede la copia un file o una cartella del
+ progetto (mantenendone la storia).\\
+ \texttt{move} &\texttt{mv}& Richiede lo spostamento un file o una
+ directory (equivalente ad un \texttt{cp}
+ seguito da un \texttt{rm}).\\
+ \texttt{update} & -- & Aggiorna la copia locale.\\
+ \texttt{resolved}& -- & Rimuove una situazione di conflitto presente
+ su un file.\\
+ \hline
+ \end{tabular}
+ \caption{Tabella riassuntiva dei principali sotto-comandi di \texttt{svn}.}
+ \label{tab:svn_mainsubcommands}
+\end{table}
+
+In genere però è piuttosto raro iniziare un progetto totalmente da zero, è
+molto più comune avere una qualche versione iniziale dei propri file
+all'interno di una cartella. In questo caso il primo passo è quello di
+eseguire una inizializzazione del \textit{repository} importando al suo
+interno quanto già esistente. Per far questo occorre eseguire il comando:
\begin{verbatim}
-cvs -d :ext:utente@server:/usr/local/cvsroot comando
+svn import [/pathname] URL
\end{verbatim}
-\normalsize
-
-questo però comporta che sulla macchina remota \texttt{server} sia installato
-il server \texttt{ssh} ed esista l'utente \texttt{utente} con privilegi di
-accesso ai file; inoltre sulla macchina ospite deve esser stata definita la
-variabile di shell \texttt{CVS\_RSH=ssh}.
-
-In questo modo ssh si collega alla macchina remota ed esegue il comando CVS con
-una connessione criptata dopo aver richiesto la password di \texttt{utente}.
-
-
-\subsection{Utilizzo di \texttt{cvs}}
-
-Per creare un repositorio a partire da un gruppo di programmi esistente basta
-dare il comando \texttt{cvs import project tag release} nella directory dei
-sorgenti; verrà creato nel repositorio il modulo di nome \texttt{project} a
-cui poi si potrà accedere con i successivi comandi; \texttt{tag} è una
-etichetta di versione iniziale (ex. \texttt{1.1.1}) dato a tutto il blocco e
-\texttt{release} una etichetta di versione data ai programmi.
-
-Una volta creato il repositorio è d'uopo cancellare la directory e ripartire
-dal progetto appena creato. Per recuperare ex-novo tutti i file di un progetto
-il comando da dare è:
-\small
+questo può essere eseguito direttamente nella directory contenente la versione
+iniziale dei propri sorgenti nel qual caso il comando richiede come ulteriore
+argomento la directory o la URL con la quale indicare il \textit{repository}
+da usare. Alternativamente si può passare come primo argomento il pathname
+della directory da importare, seguito dall'indicazione della URL del
+\textit{repository}.
+
+Si tenga presente che l'operazione di importazione inserisce sul
+\textit{repository} il contenuto completo della directory indicata, compresi
+eventuali file nascosti e sotto-directory. È anche possibile eseguire
+l'importazione di più directory da inserire in diverse sezioni del
+\textit{repository}, ma un tal caso ciascuna importazione sarà vista con una
+diversa \textit{release}. Ad ogni operazione di modifica del
+\textit{repository} viene infatti assegnato un numero progressivo che consente
+di identificarne la storia delle modifiche e riportarsi ad un dato punto della
+stessa in ogni momento successivo.\footnote{a differenza di CVS Subversion non
+ assegna un numero di versione progressivo distinto ad ogni file, ma un
+ numero di \textit{release} progressivo ad ogni cambiamento globale del
+ repository, pertanto non esiste il concetto di versione di un singolo file,
+ quanto di stato di tutto il \textit{repository} ad un dato momento, è
+ comunque possibile richiedere in maniera indipendente la versione di ogni
+ singolo file a qualunque \textit{release} si desideri.}
+
+Una volta eseguita l'importazione di una versione iniziale è d'uopo cancellare
+la directory originale e ripartire dal progetto appena creato. L'operazione di
+recuperare ex-novo di tutti i file che fanno parte di un progetto, chiamata
+usualmente \textit{checkout}, viene eseguita con il
+comando:\footnote{alternativamente si può usare l'abbreviazione \texttt{svn
+ co}.}
+\begin{verbatim}
+svn checkout URL [/pathname]
+\end{verbatim}
+che creerà nella directory corrente una directory corrispondente al nome
+specificato in coda alla URL passata come argomento, scaricando l'ultima
+versione dei file archiviati sul repository; alternativamente si può
+specificare come ulteriore argomento la directory su cui scaricare i file.
+
+Sia in caso di \texttt{import} che di \texttt{checkout} è sempre possibile
+operare su una qualunque sotto cartella contenuta all'interno di un
+\textit{repository}, ignorando totalmente quello che sta al di sopra, basterà
+indicare in sede di importazione o di estrazione iniziale un pathname o una
+URL che identifichi quella parte del progetto.
+
+Se quando si effettua lo scaricamento non si vuole usare la versione più
+aggiornata, ma una versione precedente si può usare l'opzione \texttt{-r}
+seguita da un numero che scaricherà esattamente quella \textit{release},
+alternativamente al posto del numero si può indicare una data, e verrà presa
+la \textit{release} più prossima a quella data.
+
+A differenza di CVS Subversion non supporta l'uso di \textsl{etichette}
+associate ad una certa versione del proprio progetto, per questo è invalso
+l'uso di strutturare il repository secondo lo schema illustrato inizialmente;
+è infatti molto semplice (e non comporta nessun tipo di aggravio) creare delle
+copie complete di una qualunque parte del \textit{repository} su un'altra
+parte dello stesso, per cui se si è eseguito lo sviluppo sulla cartella
+\texttt{trunk} sarà possibile creare banalmente una versione con etichetta
+\texttt{label} (o quel che si preferisce) semplicemente con una copia eseguita
+con:
\begin{verbatim}
-cvs [-d ...] checkout project [-r rel] [-D date]
+svn cp trunk tags/label
\end{verbatim}
-\normalsize che creerà la directory \texttt{project} nella directory corrente
-con l'ultima versione dei file archiviata; se non si vuole la versione più
-aggiornata, ma una versione precedente si può usare l'opzione \texttt{-r} che
-scaricherà la versione identificata dall'etichetta specificata (vedi la parte
-seguente sul comando \texttt{tag}) o l'opzione \texttt{-D} che scaricherà la
-versione più recente prima della data specificata.
-
-Una volta scaricato il progetto è possibile evitare di specificare la
-directory base del repositorio con l'opzione \texttt{-d} qualora i comandi
-vengano dati all'interno della directory creata, essa viene tenuta nel file
-\texttt{CVS/Root}, e può essere cambiata (qualora si usino più repositori)
-editando detto file.
+
+Il risultato di questo comando è la creazione della nuova cartella
+\texttt{label} sotto \texttt{tags}, che sarà assolutamente identica, nel
+contenuto (e nella sua storia) a quanto presente in \texttt{trunk} al momento
+dell'esecuzione del comando. In questo modo, una volta salvate le
+modifiche,\footnote{la copia viene eseguita localmente verrà creata anche sul
+ \textit{repository} solo dopo un \textit{commit}.} si potrà ottenere la
+versione \texttt{label} del proprio progetto semplicemente eseguendo un
+\textit{checkout} di \texttt{tags/label} in un'altra
+directory.\footnote{ovviamente una volta presa la suddetta versione si deve
+ aver cura di non eseguire nessuna modifica a partire dalla stessa, per
+ questo se si deve modificare una versione etichettata si usa
+ \texttt{branches}.}
Una volta creata la propria copia locale dei programmi, è possibile lavorare
-su di essi stando nella relativa directory,
-e apportare tutte le modifiche che si vogliono; due comandi
-permettono di schedulare la rimozione o l'aggiunta di file al repositorio:
-\small
+su di essi ponendosi nella relativa directory, e apportare tutte le modifiche
+che si vogliono ai file ivi presenti; due comandi permettono inoltre di
+schedulare la rimozione o l'aggiunta di file al
+\textit{repository}:\footnote{a differenza di CVS si possono aggiungere e
+ rimuovere, ed anche spostare con \texttt{svn mv}, sia file che directory.}
\begin{verbatim}
-cvs add file1.c
-cvs remove file2.c
+svn add file1.c
+svn remove file2.c
\end{verbatim}
-\normalsize
-ma niente viene modificato nel repositorio fintanto che non viene dato il
-comando \texttt{commit}:
-\small
+ma niente viene modificato sul \textit{repository} fintanto che non viene
+eseguito il cosiddetto \textit{commit} delle modifiche, vale a dire fintanto
+che non viene dato il comando:\footnote{in genere anche questo viene
+ abbreviato, con \texttt{svn ci}.}
\begin{verbatim}
-cvs commit [file]
+svn commit [file]
+\end{verbatim}
+ed è possibile eseguire il \textit{commit} delle modifiche per un singolo
+file, indicandolo come ulteriore argomento, mentre se non si indica nulla
+verranno inviate tutte le modifiche presenti.
+
+Si tenga presente però che il \textit{commit} non verrà eseguito se nel
+frattempo i file del \textit{repository} sono stati modificati; in questo caso
+\texttt{svn} rileverà la presenza di differenze fra la propria
+\textit{release} e quella del \textit{repository} e chiederà che si effettui
+preventivamente un aggiornamento. Questa è una delle operazioni di base di
+Subversion, che in genere si compie tutte le volte che si inizia a lavorare,
+il comando che la esegue è:
+\begin{verbatim}
+svn update
\end{verbatim}
-(è possibile mandare le modifiche anche per il singolo file).
-
-Questi comandi comunque non effettuano le modifiche se i file del repositorio
-nel frattempo sono stati modificati; in questo caso rilevano le differenze e
-restituiscono un \textit{merging} delle versioni locale/globale nella
-directory di lavoro, che è compito del programmatore esaminare per eliminare
-eventuali contrasti.
-
-Per esempio viene eseguito un commit su una versione già modificata da un
-altro sul repositorio, il programma segnalerà che c'è un conflitto e
-chiederà al ``committente'' di intervenire sui file per i quali sono stati
-rilevati i conflitti .
-Le sezioni di codice in conflitto sono separate come:
+Questo comando opera a partire dalla directory in cui viene eseguito e ne
+aggiorna il contenuto (compreso quello di eventuali sotto-directory) alla
+versione presente, scaricando le ultime versioni dei file esistenti o nuovi
+file o directory aggiunte, cancellando eventuali file e directory rimossi dal
+\textit{repository}. Esso inoltre esso cerca, in caso di presenza di
+modifiche eseguite in maniera indipendente sulla propria copia locale, di
+eseguire un \textsl{raccordo} (il cosiddetto \textit{merging}) delle stesse
+con quelle presenti sulla versione del \textit{repository}.
+
+Fintanto che sono state modificate parti indipendenti di un file di testo in
+genere il processo di \textit{merging} ha successo e le modifiche vengono
+incorporate automaticamente in conseguenza dell'aggiornamento, ma quando le
+modifiche attengono alla stessa parte di un file nel ci si troverà di fronte
+ad un conflitto ed a quel punto sarà richiesto al ``committente'' di
+intervenire manualmente sui file per i quali sono stati rilevati i conflitti
+per risolverli.
+
+Per aiutare il committente nel suo compito quando l'operazione di
+aggiornamento fallisce nel raccordo delle modifiche lascia sezioni di codice
+in conflitto opportunamente marcate e separate fra loro come nell'esempio
+seguente:
\begin{verbatim}
-<<<<<<< Makefile
+<<<<<<< .mine
$(CC) $(CFLAGS) -o pamacq pamacq.c -lm
=======
$(CC) $(CFLAGS) -o pamacq pamacq.c
->>>>>>> 1.22
+>>>>>>> r.122
+\end{verbatim}
+
+In questo caso si c'è stata una modifica sul file (mostrata nella parte
+superiore) incompatibile con quella fatta nel \textit{repository} (mostrata
+nella parte inferiore). Prima di eseguire un \textit{commit} occorrerà
+pertanto integrare le modifiche e salvare nuovamente il file rimuovendo i
+marcatori, inoltre prima che il \textit{commit} ritorni possibile si dovrà
+esplicitare la risoluzione del conflitto con il comando:
+\begin{verbatim}
+svn resolved file
\end{verbatim}
-nel caso si c'è stata una modifica sul file (mostrata nella parte superiore)
-incompatibile con quella fatta nel repositorio (mostrata nella parte
-inferiore). Prima di eseguire un \textit{commit} occorre pertanto integrare le
-modifiche e salvare nuovamente il file; a questo punto il \textit{commit} diventa
-possibile.
-
-\subsection{I principali sotto comandi}
-
-I principali sotto-comandi di \texttt{cvs} utilizzati per controllare lo stato
-dei sorgenti sono:
-
-\begin{itemize}
-\item \texttt{cvs update} \\
- scarica le eventuali modifiche dei file del repositorio e le applica ai file
- nella directory corrente. In caso di conflitti con modifiche locali effettua
- un \textit{merging} con le caratteristiche esposte in precedenza.
-
-\item \texttt{cvs status} \\
- compara i file nella directory locale con quelli del repositorio e stampa a
- schermo le informazioni di stato di ciascuno di essi:
-\begin{itemize}
-\item \texttt{Locally Modified} il file è stato modificato localmente
-\item \texttt{Locally Added} il file è stato aggiunto localmente
-\item \texttt{Up to date} il file è identico
-\item \texttt{Needs Patch} il file è cambiato sul repositorio (va aggiornato)
-\item \texttt{Needs Merge} il file è cambiato sul repositorio e localmente, le
- differenze vanno riunite prima del commit, in genere basta un \texttt{cvs
- update}, ma in caso di conflitti questi vanno sanati.
-
-\end{itemize}
-
-\item \texttt{cvs log} \\
- legge il giornale del modulo corrente; in questo modo si hanno le
- informazioni sullo stato del progetto all'interno del repositorio, per
- ciascun file è vengono mostrati informazioni generali su:
-\begin{itemize}
-\item release attuale
-\item presenza di eventuali ramificazioni
-\item lista di etichette simboliche
-\item i messaggi di commento salvati ad ogni \textit{commit}
-\end{itemize}
-
-\item \texttt{cvs rtag Etichetta modulo} \\
- permette di associare una etichetta alla corrente versione dei file nel
- progetto così come sono nel repositorio; in modo da poter ritornare a quello
- stato del software con il comando \texttt{cvs checkout -r Etichetta module}.
-
-\end{itemize}
-
-%TODO mettere SVN al posto di CVS
-
-
-% LocalWords: make Makefile makefile shell FC FLAGS CFLAGS pathname CERN
+
+\begin{table}[htb]
+ \centering
+ \footnotesize
+ \begin{tabular}[c]{|c|l|}
+ \hline
+ \textbf{Flag} & \textbf{Significato} \\
+ \hline
+ \hline
+ \texttt{?}& File sconosciuto.\\
+ \texttt{M}& File modificato localmente.\\
+ \texttt{A}& File aggiunto.\\
+ \texttt{C}& File con conflitto.\\
+% \const{G}& File con modifiche integrate.\\
+% \const{}& .\\
+ \hline
+ \end{tabular}
+ \caption{Caratteri associati ai vari stati dei file.}
+ \label{tab:svn_status}
+\end{table}
+
+
+Infine per capire la situazione della propria copia locale si può utilizzare
+il comando \texttt{svn status} che confronta i file presenti nella directory
+locale rispetto alla ultima versione scaricata dal \textit{repository} e per
+tutti quelli che non corrispondono stampa a schermo delle informazioni di
+stato nella forma di un carattere seguito dal nome del file, secondo quanto
+illustrato in tab.~\ref{tab:svn_status}.
+
+
+
+
+% LocalWords: make Makefile makefile shell FC FLAGS CFLAGS pathname CERN SCM
% LocalWords: OBJ commondef readfile FFLAGS Cuncurrent Version System CVS home
% LocalWords: adidsp geometry muonacq andaranno CVSROOT startup cvs ssh rsh to
-% LocalWords: project tag Root commit update merging Locally Modified Added
-% LocalWords: Needs Patch Merge log rtag checkout module altrobersaglio
-% LocalWords:
+% LocalWords: project tag Root commit update merging Locally Modified Added co
+% LocalWords: Needs Patch Merge log rtag checkout module altrobersaglio Source
+% LocalWords: Control Subversion repository DAV svnserve URL svn subversion
+% LocalWords: client sez svnadmin Truelite Srl trunk tags branches tab add rm
+% LocalWords: remove copy cp move resolved label
Si deve comunque tenere presente che fino al kernel 2.6.16 la precisione di
queste funzioni era limitata dalla frequenza del timer di sistema,\footnote{il
- valore della constante \texttt{HZ}, di cui abbiamo già parlato in
+ valore della costante \texttt{HZ}, di cui abbiamo già parlato in
sez.~\ref{sec:proc_hierarchy}.} in quanto le temporizzazioni erano calcolate
-in numero di interruzioni del timer (i cosiddetti ''\textit{jiffies}''), ed era
-assicurato soltanto che il segnale non sarebbe stato mai generato prima della
-scadenza programmata (l'arrotondamento cioè era effettuato per
-eccesso).\footnote{questo in realtà non è del tutto vero a causa di un bug,
- presente fino al kernel 2.6.12, che in certe circostanze causava l'emissione
- del segnale con un arrotondamento per difetto.} L'uso del contatore dei
-\textit{jiffies}, un intero a 32 bit, comportava inoltre l'impossibilità di
-specificare tempi molto lunghi.\footnote{superiori al valore della costante
+in numero di interruzioni del timer (i cosiddetti \itindex{jiffies}
+''\textit{jiffies}''), ed era assicurato soltanto che il segnale non sarebbe
+stato mai generato prima della scadenza programmata (l'arrotondamento cioè era
+effettuato per eccesso).\footnote{questo in realtà non è del tutto vero a
+ causa di un bug, presente fino al kernel 2.6.12, che in certe circostanze
+ causava l'emissione del segnale con un arrotondamento per difetto.} L'uso
+del contatore dei \itindex{jiffies} \textit{jiffies}, un intero a 32 bit,
+comportava inoltre l'impossibilità di specificare tempi molto
+lunghi.\footnote{superiori al valore della costante
\const{MAX\_SEC\_IN\_JIFFIES}, pari, nel caso di default di un valore di
\const{HZ} di 250, a circa 99 giorni e mezzo.} Con il cambiamento della
rappresentazione effettuato nel kernel 2.6.16 questo problema è scomparso e
conto poi che in caso di sistema molto carico, si può avere il caso patologico
in cui un timer scade prima che il segnale di una precedente scadenza sia
stato consegnato; in questo caso, per il comportamento dei segnali descritto
-in sez.~\ref{sec:sig_sigchld}, un solo segnale sarà consegnato.
+in sez.~\ref{sec:sig_sigchld}, un solo segnale sarà consegnato. Per questo
+oggi l'uso di questa funzione è deprecato a favore dei \textit{POSIX timer}
+che tratteremo in sez.~\ref{sec:sig_timer_adv}.
Dato che sia \func{alarm} che \func{setitimer} non consentono di leggere il
valore corrente di un timer senza modificarlo, è possibile usare la funzione
Come si può notare in fig.~\ref{fig:sig_sigaction} \func{sigaction} permette
di utilizzare due forme diverse di gestore,\footnote{la possibilità è prevista
dallo standard POSIX.1b, ed è stata aggiunta nei kernel della serie 2.1.x
- con l'introduzione dei segnali real-time (vedi
+ con l'introduzione dei segnali \textit{real-time} (vedi
sez.~\ref{sec:sig_real_time}); in precedenza era possibile ottenere alcune
informazioni addizionali usando \var{sa\_handler} con un secondo parametro
addizionale di tipo \var{sigcontext}, che adesso è deprecato.} da
\end{figure}
In generale \var{si\_code} contiene, per i segnali generici, per quelli
-real-time e per tutti quelli inviati tramite da un processo con \func{kill} o
-affini, le informazioni circa l'origine del segnale stesso, ad esempio se
-generato dal kernel, da un timer, da \func{kill}, ecc. Il valore viene sempre
-espresso come una costante,\footnote{le definizioni di tutti i valori
- possibili si trovano in \file{bits/siginfo.h}.} ed i valori possibili in
-questo caso sono riportati in tab.~\ref{tab:sig_si_code_generic}.
+\textit{real-time} e per tutti quelli inviati tramite da un processo con
+\func{kill} o affini, le informazioni circa l'origine del segnale stesso, ad
+esempio se generato dal kernel, da un timer, da \func{kill}, ecc. Il valore
+viene sempre espresso come una costante,\footnote{le definizioni di tutti i
+ valori possibili si trovano in \file{bits/siginfo.h}.} ed i valori possibili
+in questo caso sono riportati in tab.~\ref{tab:sig_si_code_generic}.
Nel caso di alcuni segnali però il valore di \var{si\_code} viene usato per
fornire una informazione specifica relativa alle motivazioni della ricezione
Il resto della struttura \struct{siginfo\_t} è definito come \ctyp{union} ed i
valori eventualmente presenti dipendono dal segnale, così \const{SIGCHLD} ed i
-segnali real-time (vedi sez.~\ref{sec:sig_real_time}) inviati tramite
+segnali \textit{real-time} (vedi sez.~\ref{sec:sig_real_time}) inviati tramite
\func{kill} avvalorano \var{si\_pid} e \var{si\_uid} coi valori corrispondenti
al processo che ha emesso il segnale, \const{SIGCHLD} avvalora anche i campi
-\const{si\_status}, \const{si\_utime} e \const{si\_stime} che indicano
+\var{si\_status}, \var{si\_utime} e \var{si\_stime} che indicano
rispettivamente lo stato di uscita, l'\textit{user time} e il \textit{system
time} (vedi sez.~\ref{sec:sys_cpu_times}) usati dal processo;
\const{SIGILL}, \const{SIGFPE}, \const{SIGSEGV} e \const{SIGBUS} avvalorano
Abbiamo finora parlato dei gestori dei segnali come funzioni chiamate in
corrispondenza della consegna di un segnale. In realtà un gestore non può
essere una funzione qualunque, in quanto esso può essere eseguito in
-corrispondenza all'interruzione in un punto qualunque del programma principale,
-ed ad esempio può essere problematico chiamare all'interno di un gestore di
-segnali la stessa funzione che dal segnale è stata interrotta.
+corrispondenza all'interruzione in un punto qualunque del programma
+principale, cosa che ad esempio può rendere problematico chiamare all'interno
+di un gestore di segnali la stessa funzione che dal segnale è stata
+interrotta.
\index{funzioni!sicure|(}
Il concetto è comunque più generale e porta ad una distinzione fra quelle che
-che POSIX chiama \textsl{funzioni insicure} (\textit{unsafe function}) e
-\textsl{funzioni sicure} (\textit{safe function}); quando un segnale
-interrompe una funzione insicura ed il gestore chiama al suo interno una
-funzione insicura il sistema può dare luogo ad un comportamento indefinito.
-
-Tutto questo significa che un gestore di segnale deve essere programmato con
-molta cura per evitare questa evenienza, pertanto è non è possibile chiamare
-al suo interno una funzione qualunque, e si può ricorrere soltanto all'uso di
-funzioni sicure.
-
-L'elenco delle funzioni sicure varia a secondo dello standard a cui si fa
-riferimento, secondo quanto riportato dallo standard POSIX 1003.1 nella
+POSIX chiama \textsl{funzioni insicure} (\textit{signal unsafe function}) e
+\textsl{funzioni sicure} (o più precisamente \textit{signal safe function});
+quando un segnale interrompe una funzione insicura ed il gestore chiama al suo
+interno una funzione insicura il sistema può dare luogo ad un comportamento
+indefinito, la cosa non avviene invece per le funzioni sicure.
+
+Tutto questo significa che la funzione che si usa come gestore di segnale deve
+essere programmata con molta cura per evirare questa evenienza e che non è
+possibile utilizzare al suo interno una qualunque funzione di sistema, se si
+vogliono evitare questi problemi si può ricorrere soltanto all'uso delle
+funzioni considerate sicure.
+
+L'elenco delle funzioni considerate sicure varia a seconda della
+implementazione utilizzata e dello standard a cui si fa
+riferimento;\footnote{non è riportata una lista specifica delle funzioni
+ sicure per Linux, si suppone pertanto che siano quelle richieste dallo
+ standard.} secondo quanto riportato dallo standard POSIX 1003.1 nella
revisione del 2003, le ``\textit{signal safe function}'' che possono essere
-chiamate anche all'interno di un gestore di segnali sono quelle della lista
-riportata in fig.~\ref{fig:sig_safe_functions}.
+chiamate anche all'interno di un gestore di segnali sono tutte quelle della
+lista riportata in fig.~\ref{fig:sig_safe_functions}.
\begin{figure}[!htb]
\footnotesize \centering
- \begin{minipage}[c]{15cm}
+ \begin{minipage}[c]{14cm}
\func{\_exit}, \func{abort}, \func{accept}, \func{access},
\func{aio\_error} \func{aio\_return}, \func{aio\_suspend}, \func{alarm},
\func{bind}, \func{cfgetispeed}, \func{cfgetospeed}, \func{cfsetispeed},
\index{funzioni!sicure|)}
+Lo standard POSIX.1-2004 modifica la lista di
+fig.~\ref{fig:sig_safe_functions} aggiungendo le funzioni \func{\_Exit} e
+\func{sockatmark}, mentre lo standard POSIX.1-2008 rimuove della lista le tre
+funzioni \func{fpathconf}, \func{pathconf}, \func{sysconf} e vi aggiunge le
+ulteriori funzioni in fig.~\ref{fig:sig_safe_functions_posix_2008}.
+
+\begin{figure}[!htb]
+ \footnotesize \centering
+ \begin{minipage}[c]{14cm}
+ \func{execl}, \func{execv}, \func{faccessat}, \func{fchmodat},
+ \func{fchownat}, \func{fexecve}, \func{fstatat}, \func{futimens},
+ \func{linkat}, \func{mkdirat}, \func{mkfifoat}, \func{mknod},
+ \func{mknodat}, \func{openat}, \func{readlinkat}, \func{renameat},
+ \func{symlinkat}, \func{unlinkat}, \func{utimensat}, \func{utimes}.
+ \end{minipage}
+ \normalsize
+ \caption{Ulteriori funzioni sicure secondo lo standard POSIX.1-2008.}
+ \label{fig:sig_safe_functions_posix_2008}
+\end{figure}
+
+
Per questo motivo è opportuno mantenere al minimo indispensabile le operazioni
effettuate all'interno di un gestore di segnali, qualora si debbano compiere
operazioni complesse è sempre preferibile utilizzare la tecnica in cui si usa
gestione avanzata delle temporizzazioni e le nuove interfacce per la gestione
di segnali ed eventi attraverso l'uso di file descriptor.
-\subsection{I segnali real-time}
+\subsection{I segnali \textit{real-time}}
\label{sec:sig_real_time}
Lo standard POSIX.1b, nel definire una serie di nuove interfacce per i servizi
sez.~\ref{sec:sig_sigaction}, è disponibile anche con i segnali ordinari, si
applicano solo ai nuovi segnali \textit{real-time}; questi ultimi sono
accessibili in un intervallo di valori specificati dalle due costanti
-\const{SIGRTMIN} e \const{SIGRTMAX},\footnote{in Linux di solito (cioè sulla
- piattaforma i386) il primo valore è 33, ed il secondo \code{\_NSIG-1}, che
- di norma è 64, per un totale di 32 segnali disponibili, contro gli almeno 8
- richiesti da POSIX.1b.} che specificano il numero minimo e massimo associato
-ad un segnale real-time.
-
-% TODO rivedere secondo man 7 signal con le informazioni aggiornate sul numero
-% di segnali real-time disponibili
+\const{SIGRTMIN} e \const{SIGRTMAX}, che specificano il numero minimo e
+massimo associato ad un segnale \textit{real-time}.
+
+Su Linux di solito il primo valore è 33, mentre il secondo è \code{\_NSIG-1},
+che di norma (vale a dire sulla piattaforma i386) è 64. Questo dà un totale di
+32 segnali disponibili, contro gli almeno 8 richiesti da POSIX.1b. Si tenga
+presente però che i primi segnali \textit{real-time} disponibili vendono usati
+dalle \acr{glibc} per l'implementazione dei \textit{thread} POSIX (vedi
+sez.~\ref{sec:thread_posix_intro}), ed il valore di \const{SIGRTMIN} viene
+modificato di conseguenza.\footnote{vengono usati i primi tre per la vecchia
+ implementazione dei \textit{LinuxThread} ed i primi due per la nuova NTPL
+ (\textit{New Thread Posix Library}), il che comporta che \const{SIGRTMIN} a
+ seconda dei casi può essere 34 o 35.}
+
+Per questo motivo nei programmi che usano i segnali \textit{real-time} non si
+deve mai usare un valore assoluto dato che si correrebbe il rischio di
+utilizzare un segnale in uso alle librerie, ed il numero del segnale deve
+invece essere sempre specificato in forma relativa a \const{SIGRTMIN} (come
+\code{SIGRTMIN + n}) avendo inoltre cura di controllare di non aver mai
+superato \const{SIGRTMAX}.
I segnali con un numero più basso hanno una priorità maggiore e vengono
consegnati per primi, inoltre i segnali \textit{real-time} non possono
riguardo ma Linux, come molte altre implementazioni, adotta questa
politica.}
-
Si tenga presente che questi nuovi segnali non sono associati a nessun evento
-specifico, a meno di non utilizzarli in meccanismi di notifica come quelli per
-l'I/O asincrono (vedi sez.~\ref{sec:file_asyncronous_io}) o per le code di
-messaggi POSIX (vedi sez.~\ref{sec:ipc_posix_mq}); pertanto devono essere
-inviati esplicitamente.
+specifico, a meno di non richiedere specificamente il loro utilizzo in
+meccanismi di notifica come quelli per l'I/O asincrono (vedi
+sez.~\ref{sec:file_asyncronous_io}) o per le code di messaggi POSIX (vedi
+sez.~\ref{sec:ipc_posix_mq}); pertanto devono essere inviati esplicitamente.
Inoltre, per poter usufruire della capacità di restituire dei dati, i relativi
gestori devono essere installati con \func{sigaction}, specificando per
\var{sa\_flags} la modalità \const{SA\_SIGINFO} che permette di utilizzare la
forma estesa \var{sa\_sigaction} (vedi sez.~\ref{sec:sig_sigaction}). In
-questo modo tutti i segnali real-time possono restituire al gestore una serie
-di informazioni aggiuntive attraverso l'argomento \struct{siginfo\_t}, la cui
-definizione è stata già vista in fig.~\ref{fig:sig_siginfo_t}, nella
-trattazione dei gestori in forma estesa.
+questo modo tutti i segnali \textit{real-time} possono restituire al gestore
+una serie di informazioni aggiuntive attraverso l'argomento
+\struct{siginfo\_t}, la cui definizione è stata già vista in
+fig.~\ref{fig:sig_siginfo_t}, nella trattazione dei gestori in forma estesa.
-In particolare i campi utilizzati dai segnali real-time sono \var{si\_pid} e
-\var{si\_uid} in cui vengono memorizzati rispettivamente il \acr{pid} e
-l'user-ID effettivo del processo che ha inviato il segnale, mentre per la
-restituzione dei dati viene usato il campo \var{si\_value}.
-
-Questo è una \ctyp{union} di tipo \struct{sigval\_t} (la sua definizione è in
-fig.~\ref{fig:sig_sigval}) in cui può essere memorizzato o un valore numerico,
-se usata nella forma \var{sival\_int}, o un indirizzo, se usata nella forma
-\var{sival\_ptr}. L'unione viene usata dai segnali real-time e da vari
-meccanismi di notifica\footnote{un campo di tipo \struct{sigval\_t} è presente
- anche nella struttura \struct{sigevent} (definita in
- fig.~\ref{fig:file_sigevent}) che viene usata dai meccanismi di notifica
- come quelli per l'I/O asincrono (vedi sez.~\ref{sec:file_asyncronous_io}) o
- le code di messaggi POSIX (vedi sez.~\ref{sec:ipc_posix_mq}).} per
-restituire dati al gestore del segnale; in alcune definizioni essa viene
-identificata anche come \code{union sigval}.
+In particolare i campi utilizzati dai segnali \textit{real-time} sono
+\var{si\_pid} e \var{si\_uid} in cui vengono memorizzati rispettivamente il
+\acr{pid} e l'user-ID effettivo del processo che ha inviato il segnale, mentre
+per la restituzione dei dati viene usato il campo \var{si\_value}.
\begin{figure}[!htb]
\footnotesize \centering
\label{fig:sig_sigval}
\end{figure}
+Questo è una \ctyp{union} di tipo \struct{sigval\_t} (la sua definizione è in
+fig.~\ref{fig:sig_sigval}) in cui può essere memorizzato o un valore numerico,
+se usata nella forma \var{sival\_int}, o un indirizzo, se usata nella forma
+\var{sival\_ptr}. L'unione viene usata dai segnali \textit{real-time} e da
+vari meccanismi di notifica\footnote{un campo di tipo \struct{sigval\_t} è
+ presente anche nella struttura \struct{sigevent} (definita in
+ fig.~\ref{fig:file_sigevent}) che viene usata dai meccanismi di notifica
+ come quelli per l'I/O asincrono (vedi sez.~\ref{sec:file_asyncronous_io}) o
+ le code di messaggi POSIX (vedi sez.~\ref{sec:ipc_posix_mq}).} per
+restituire dati al gestore del segnale; in alcune definizioni essa viene
+identificata anche come \code{union sigval}.
+
A causa delle loro caratteristiche, la funzione \func{kill} non è adatta ad
inviare segnali \textit{real-time}, poiché non è in grado di fornire alcun
valore per \struct{sigval\_t}; per questo motivo lo standard ha previsto una
Se il segnale è bloccato la funzione ritorna immediatamente, se si è
installato un gestore con \const{SA\_SIGINFO} e ci sono risorse disponibili,
-(vale a dire che c'è posto\footnote{la profondità della coda è indicata dalla
- costante \const{SIGQUEUE\_MAX}, una della tante costanti di sistema definite
+(vale a dire che c'è posto nella coda dei segnali \textit{real-time}) esso
+viene inserito e diventa pendente; una volta consegnato riporterà nel campo
+\var{si\_code} di \struct{siginfo\_t} il valore \const{SI\_QUEUE} e il campo
+\var{si\_value} riceverà quanto inviato con \param{value}. Se invece si è
+installato un gestore nella forma classica il segnale sarà generato, ma tutte
+le caratteristiche tipiche dei segnali \textit{real-time} (priorità e coda)
+saranno perse.
+
+Secondo lo standard POSIX la profondità della coda è indicata dalla costante
+\const{SIGQUEUE\_MAX},\footnote{una della tante costanti di sistema definite
dallo standard POSIX che non abbiamo riportato esplicitamente in
- sez.~\ref{sec:sys_limits}; il suo valore minimo secondo lo standard,
- \const{\_POSIX\_SIGQUEUE\_MAX}, è pari a 32. Nel caso di Linux questo è uno
- dei parametri del kernel impostabili sia con \func{sysctl}, che scrivendolo
- direttamente in \procfile{/proc/sys/kernel/rtsig-max}, il valore predefinito
- è di 1024.} nella coda dei segnali real-time) esso viene inserito e diventa
-pendente; una volta consegnato riporterà nel campo \var{si\_code} di
-\struct{siginfo\_t} il valore \const{SI\_QUEUE} e il campo \var{si\_value}
-riceverà quanto inviato con \param{value}. Se invece si è installato un
-gestore nella forma classica il segnale sarà generato, ma tutte le
-caratteristiche tipiche dei segnali real-time (priorità e coda) saranno perse.
+ sez.~\ref{sec:sys_limits}.} il suo valore minimo secondo lo standard,
+\const{\_POSIX\_SIGQUEUE\_MAX}, è pari a 32. Nel caso di Linux la coda ha una
+dimensione variabile; fino alla versione 2.6.7 c'era un limite massimo globale
+che poteva essere impostato come parametro del kernel in
+\procfile{/proc/sys/kernel/rtsig-max};\footnote{ed il valore predefinito era
+ pari a 1024.} a partire dal kernel 2.6.8 il valore globale è stato rimosso e
+sostituito dalla risorsa \const{RLIMIT\_SIGPENDING} associata al singolo
+utente, che può essere modificata con \func{setrlimit} come illustrato in
+sez.~\ref{sec:sys_resource_limit}.
Lo standard POSIX.1b definisce inoltre delle nuove funzioni che permettono di
gestire l'attesa di segnali specifici su una coda, esse servono in particolar
modo nel caso dei \itindex{thread} \textit{thread}, in cui si possono usare i
-segnali real-time come meccanismi di comunicazione elementare; la prima di
-queste funzioni è \funcd{sigwait}, il cui prototipo è:
+segnali \textit{real-time} come meccanismi di comunicazione elementare; la
+prima di queste funzioni è \funcd{sigwait}, il cui prototipo è:
\begin{prototype}{signal.h}
{int sigwait(const sigset\_t *set, int *sig)}
La funzione estrae dall'insieme dei segnali pendenti uno qualunque dei segnali
specificati da \param{set}, il cui valore viene restituito in \param{sig}. Se
sono pendenti più segnali, viene estratto quello a priorità più alta (cioè con
-il numero più basso). Se, nel caso di segnali real-time, c'è più di un segnale
-pendente, ne verrà estratto solo uno. Una volta estratto il segnale non verrà
-più consegnato, e se era in una coda il suo posto sarà liberato. Se non c'è
-nessun segnale pendente il processo viene bloccato fintanto che non ne arriva
-uno.
+il numero più basso). Se, nel caso di segnali \textit{real-time}, c'è più di
+un segnale pendente, ne verrà estratto solo uno. Una volta estratto il segnale
+non verrà più consegnato, e se era in una coda il suo posto sarà liberato. Se
+non c'è nessun segnale pendente il processo viene bloccato fintanto che non ne
+arriva uno.
Per un funzionamento corretto la funzione richiede che alla sua chiamata i
segnali di \param{set} siano bloccati. In caso contrario si avrebbe un
Analoga a \func{sigwait}, ma riceve anche le informazioni associate al
segnale in \param{info}.
- \funcdecl{int sigtimedwait(const sigset\_t *set, siginfo\_t *value, const
- struct timespec *info)}
+ \funcdecl{int sigtimedwait(const sigset\_t *set, siginfo\_t *info, const
+ struct timespec *timout)}
Analoga a \func{sigwaitinfo}, con un la possibilità di specificare un
timeout in \param{timeout}.
\subsection{La gestione avanzata delle temporizzazioni}
\label{sec:sig_timer_adv}
-% TODO trattare i Posix timer, e le fuzioni:
+Sia le funzioni per la gestione dei tempi viste in
+sez.~\ref{sec:sys_cpu_times} che quelle per la gestione dei timer di
+sez.~\ref{sec:sig_alarm_abort} sono state a lungo limitate dalla risoluzione
+massima dei tempi dell'orologio interno del kernel, che era quella ottenibile
+dal timer di sistema che governa lo \textit{scheduler},\footnote{e quindi
+ limitate dalla frequenza dello stesso che si ricordi, come già illustrato in
+ sez.~\ref{sec:proc_hierarchy}, è data dal valore della costante
+ \texttt{HZ}.} i contatori usati per il calcolo dei tempo infatti erano
+basati sul numero di \itindex{jiffies} \textit{jiffies} che vengono
+incrementati ad ogni \textit{clock tick} del timer di sistema.\footnote{il che
+ comportava anche, come accennato in sez.~\ref{sec:sig_alarm_abort} per
+ \func{setitimer}, problemi per il massimo periodo di tempo copribile da
+ alcuni di questi orologi, come quelli associati al \textit{process time}
+ almeno fino a quando, con il kernel 2.6.16, non è stato rimosso il limite di
+ un valore a 32 bit per i \textit{jiffies}.}
+
+Nelle architetture moderne però tutti i computer sono dotati di temporizzatori
+hardware che possono supportare risoluzioni molto elevate, ed in maniera del
+tutto indipendente dalla frequenza scelta per il timer di sistema che governa
+lo \textit{scheduler};\footnote{normalmente si possono ottenere precisioni
+ fino al microsecondo, andando molto oltre in caso di hardware dedicato.} per
+questo lo standard POSIX ha previsto una serie di nuove funzioni relative a a
+quelli che vengono chiamati ``\textsl{orologi} \textit{real-time}'', in grado
+di supportare risoluzioni fino al nanosecondo. Inoltre le CPU più moderne sono
+dotate a loro volta di contatori ad alta definizione che consentono una grande
+accuratezza nella misura del tempo da esse dedicato all'esecuzione di un
+processo.
+
+Per usare queste funzionalità ed ottenere risoluzioni temporali più accurate,
+occorre però un opportuno supporto da parte del kernel, ed i cosiddetti
+\textit{high resolution timer} che consentono di fare ciò sono stati
+introdotti nel kernel ufficiale solo a partire dalla versione
+2.6.21.\footnote{deve essere stata abilitata l'opzione di compilazione
+ \texttt{CONFIG\_HIGH\_RES\_TIMERS}, erano però disponibili anche in
+ precedenza come patch facenti parte dello sviluppo delle estensioni
+ \textit{real-time} del kernel, per cui alcune distribuzioni possono avere
+ questo supporto anche con versioni precedenti del kernel.} Le funzioni
+definite dallo standard POSIX per gestire orologi ad alta definizione però
+erano già presenti, essendo stata introdotte insieme ad altre funzioni per il
+supporto delle estensioni \textit{real-time} con il rilascio del kernel 2.6,
+ma la risoluzione effettiva era nominale.
+
+A tutte le implementazioni che si rifanno a queste estensioni è richiesto di
+disporre di una versione \textit{real-time} almeno per l'orologio generale di
+sistema, quello che mantiene il \textit{calendar time} (vedi
+sez.~\ref{sec:sys_time_base}), che in questa forma deve indicare il numero di
+secondi e nanosecondi passati a partire dal primo gennaio 1970 (\textit{The
+ Epoch}).\footnote{si ricordi che l'orologio ordinario usato dal
+ \textit{calendar time} riporta solo un numero di secondi, e che la
+ risoluzione effettiva normalmente non raggiunge il nanosecondo (a meno di
+ hardware specializzato).} Oltre all'orologio generale di sistema possono
+essere presenti altri tipi di orologi \textit{real-time}, ciascuno dei quali
+viene identificato da un opportuno valore di una variabile di tipo
+\type{clockid\_t}; un elenco di quelli disponibili su Linux è riportato in
+tab.~\ref{tab:sig_timer_clockid_types}.
+
+\begin{table}[htb]
+ \footnotesize
+ \centering
+ \begin{tabular}[c]{|l|p{8cm}|}
+ \hline
+ \textbf{Valore} & \textbf{Significato} \\
+ \hline
+ \hline
+ \const{CLOCK\_REALTIME} & Orologio \textit{real-time} di sistema, può
+ essere impostato solo con privilegi
+ amministrativi.\\
+ \const{CLOCK\_MONOTONIC} & Orologio che indica un tempo monotono
+ crescente (a partire da un tempo iniziale non
+ specificati) che non può essere modificato.\\
+ \const{CLOCK\_MONOTONIC\_RAW}&Simile al precedente, ma non subisce gli
+ aggiustamenti dovuti all'uso di NTP (viene
+ usato per fare riferimento ad una fonte
+ hardware.\footnotemark\\
+ \const{CLOCK\_PROCESS\_CPUTIME\_ID}& contatore del tempo di CPU usato
+ da un processo (il \textit{process time} di
+ sez.~\ref{sec:sys_cpu_times}, nel totale di
+ \textit{system time} e \textit{user time})
+ comprensivo di tutto il tempo di CPU usato
+ da eventuali \itindex{thread}
+ \textit{thread}.\\
+ \const{CLOCK\_THREAD\_CPUTIME\_ID}& contatore del tempo di CPU
+ (\textit{user time} e \textit{system time})
+ usato da un singolo \itindex{thread}
+ \textit{thread}.\\
+% \const{} & .\\
+ \hline
+ \end{tabular}
+ \caption{Valori possibili per una variabile di tipo \type{clockid\_t}
+ usata per indicare a quale tipo di orologio si vuole fare riferimento.}
+ \label{tab:sig_timer_clockid_types}
+\end{table}
+
+\footnotetext{specifico di Linux, introdotto a partire dal kernel 2.6.28, non
+ previsto da POSIX e non presente in altri sistemi unix-like.}
+
+Per poter utilizzare queste funzionalità le \acr{glibc} richiedono che la
+macro \macro{\_POSIX\_C\_SOURCE} sia definita ad un valore maggiore o uguale
+di \texttt{199309L} (vedi sez.~\ref{sec:intro_gcc_glibc_std}), inoltre i
+programmi che le usano devono essere linkati con la libreria delle estensioni
+\textit{real-time} usando esplicitamente l'opzione \texttt{-lrt}. Si tenga
+presente inoltre che la disponibilità di queste funzionalità avanzate può
+essere controllato dalla definizione della macro \macro{\_POSIX\_TIMERS} ad un
+valore maggiore di 0, e che le ulteriori macro
+\macro{\_POSIX\_MONOTONIC\_CLOCK}, \macro{\_POSIX\_CPUTIME} e
+\macro{\_POSIX\_THREAD\_CPUTIME} indicano la presenza dei rispettivi orologi
+di tipo \const{CLOCK\_MONOTONIC}, \const{CLOCK\_PROCESS\_CPUTIME\_ID} e
+\const{CLOCK\_PROCESS\_CPUTIME\_ID}.\footnote{tutte queste macro sono definite
+ in \texttt{unistd.h}, che peranto deve essere incluso per poterle
+ controllarle.} Infine se il kernel ha il supporto per gli \textit{high
+ resolution timer} un elenco degli orologi e dei timer può essere ottenuto
+tremite il file \procfile{/proc/timer\_list}.
+
+Le due funzioni che ci consentono rispettivamente di modificare o leggere il
+valore per uno degli orologi \textit{real-time} sono \funcd{clock\_settime} e
+\funcd{clock\_gettime}; i rispettivi prototipi sono:
+\begin{functions}
+ \headdecl{time.h}
+
+ \funcdecl{int clock\_settime(clockid\_t clockid, const struct timespec *tp)}
+ \funcdecl{int clock\_gettime(clockid\_t clockid, struct timespec *tp)}
+
+ Imposta o legge un orologio \textit{real-time}.
+
+ \bodydesc{La funzione restituisce 0 in caso di successo e $-1$ in caso di
+ errore, nel qual caso \var{errno} assumerà uno dei seguenti valori:
+ \begin{errlist}
+ \item[\errcode{EINVAL}] il valore specificato per \param{clockid} non è
+ valido o il relativo orologio \textit{real-time} non è supportato dal
+ sistema.
+ \item[\errcode{EPERM}] non si ha il permesso di impostare l'orologio
+ indicato (solo per \func{clock\_settime}).
+ \item[\errcode{EFAULT}] l'indirizzo \param{tp} non è valido.
+ \end{errlist}
+}
+\end{functions}
+
+Entrambe le funzioni richiedono che si specifichi come primo argomento il tipo
+di orologio su cui si vuole operare con uno dei valori di
+tab.~\ref{tab:sig_timer_clockid_types} o con il risultato di una chiamata a
+\func{clock\_getcpuclockid} (che tratteremo a breve), il secondo argomento
+invece è sempre il puntatore \param{tp} ad una struttura \struct{timespec}
+(vedi fig.~\ref{fig:sys_timespec_struct}) che deve essere stata
+precedentemente allocata; nel primo caso questa devrà anche essere stata
+inizializzata con il valore che si vuole impostare sull'orologio, mentre nel
+secondo verrà restituito al suo interno il valore corrente dello stesso.
+
+Si tenga presente inoltre che per eseguire un cambiamento sull'orologio
+generale di sistema \const{CLOCK\_REALTIME} occorrono i privilegi
+amministrativi;\footnote{ed in particolare la \textit{capability}
+ \const{CAP\_SYS\_TIME}.} inoltre ogni cambiamento ad esso apportato non avrà
+nessun effetto sulle temporizzazioni effettuate in forma relativa, come quelle
+impostate sulle quantità di \textit{process time} o per un intervallo di tempo
+da trascorrere, ma solo su quelle che hanno richiesto una temporizzazione ad
+un istante preciso (in termini di \textit{calendar time}). Si tenga inoltre
+presente che nel caso di Linux \const{CLOCK\_REALTIME} è l'unico orologio per
+cui si può effettuare una modifica, infatti nonostante lo standard preveda la
+possibilità di modifiche anche per \const{CLOCK\_PROCESS\_CPUTIME\_ID} e
+\const{CLOCK\_THREAD\_CPUTIME\_ID}, il kernel non le consente.
+
+Oltre alle due funzioni precedenti, lo standard POSIX prevede una terza
+funzione che consenta di ottenere la risoluzione effettiva fornita da un certo
+orologio, la funzione è \funcd{clock\_getres} ed il suo prototipo è:
+\begin{functions}
+ \headdecl{time.h}
+
+ \funcdecl{int clock\_getres(clockid\_t clockid, struct timespec *res)}
+
+ Legge la risoluzione di un orologio \textit{real-time}.
+
+ \bodydesc{La funzione restituisce 0 in caso di successo e $-1$ in caso di
+ errore, nel qual caso \var{errno} assumerà uno dei seguenti valori:
+ \begin{errlist}
+ \item[\errcode{EINVAL}] il valore specificato per \param{clockid} non è
+ valido.
+ \item[\errcode{EFAULT}] l'indirizzo di \param{res} non è valido.
+ \end{errlist}
+}
+\end{functions}
+
+La funzione richiede come primo argomento l'indicazione dell' orologio di cui
+si vuole conoscere la risoluzione (effettuata allo stesso modo delle due
+precedenti) e questa verrà restituita in una struttura \struct{timespec}
+all'indirizzo puntato dall'argomento \param{res}.
+
+Come accennato il valore di questa risoluzione dipende sia dall'hardware
+disponibile che dalla implementazione delle funzioni, e costituisce il limite
+minimo di un intervallo di tempo che si può indicare, qualunque valore si
+voglia utilizzare nelle funzioni di impostazione che non corrisponda ad un
+multiplo intero di questa risoluzione, sarà troncato in maniera automatica.
+
+Si tenga presente inoltre che con l'introduzione degli \textit{high resolution
+ timer} i due orologi \const{CLOCK\_PROCESS\_CPUTIME\_ID} e
+\const{CLOCK\_THREAD\_CPUTIME\_ID} fanno riferimento ai contatori presenti in
+opportuni registri interni del processore; questo sui sistemi multiprocessore
+può avere delle ripercussioni sulla precisione delle misure di tempo che vanno
+al di là della risoluzione teorica ottenibile con \func{clock\_getres}, che
+può essere ottenuta soltanto quando si è sicuri che un processo (o un
+\textit{thread}) sia sempre stato eseguito sullo stesso processore.
+
+Con i sistemi multiprocessore infatti ogni singola CPU ha i suoi registri
+interni, e se ciascuna di esse utilizza una base di tempo diversa (se cioè il
+clock del processore non è unico) avendo queste in genere frequenze
+leggermente diverse, otterremo dei valori dei contatori scorrelati fra loro
+senza possibilità di sincronizzazione.
+
+Il problema si presenta, in forma più lieve, anche se la base di tempo è la
+stessa, dato che un sistema multiprocessore non avvia mai tutte le CPU allo
+stesso istante, si potrà così avere di nuovo una differenza fra i contatori,
+soggetta però soltanto ad uno sfasamento costante. Per questo caso il kernel
+per alcune architetture ha del codice che consente di ridurre al minimo la
+differenza, ma non può essere comunque garantito che questa si annulli (anche
+se in genere risulta molto piccola e trascurabile nella gran parte dei casi).
+
+Per poter gestire questo tipo di problematiche lo standard ha previsto una
+apposita funzione che sia in grado di ottenere l'identificativo dell'orologio
+associato al \textit{process time} di un processo, la funzione è
+\funcd{clock\_getcpuclockid} ed il suo prototipo è:
+\begin{functions}
+ \headdecl{time.h}
+
+ \funcdecl{int clock\_getcpuclockid(pid\_t pid, clockid\_t *clockid)}
+
+ Ottiene l'identificatore dell'orologio di CPU usato da un processo.
+
+ \bodydesc{La funzione restituisce 0 in caso di successo e $-1$ in caso di
+ errore, nel qual caso \var{errno} assumerà uno dei seguenti valori:
+ \begin{errlist}
+ \item[\errcode{ENOSYS}] il valore specificato per \param{clockid} non è
+ valido.
+ \item[\errcode{EPERM}] l'indirizzo di \param{res} non è valido.
+ \item[\errcode{ENOENT}] non c'è modo di avere
+ \item[\errcode{ESRCH}] non esiste il processo \param{pid}.
+ \end{errlist}
+}
+\end{functions}
+
+
+% TODO trattare gli orologi ad alta definizione e le funzioni POSIX per gli
+% stessi cioè:
% clock_getres clock_gettime clock_settime (vedi man page)
+
+Abbiamo visto in sez.~\ref{sec:sig_alarm_abort} come l'interfaccia di
+\func{setitimer} derivata da BSD presenti delle limitazioni,\footnote{in
+ particolare la possibilità di perdere un segnale sotto carico.} tanto che
+nello standard POSIX.1-2008 questa viene marcata come obsoleta, e ne viene
+fortemente consigliata la sostituzione con nuova interfaccia definita dallo
+standard POSIX.1-2001 che va sotto il nome di \textit{Posix Timer API}.
+
+La \textit{system call} per la nuova interfaccia sono stata introdotte a
+partire dal kernel 2.6, ma fino al kernel 2.6.16 la precisione degli allarmi
+era limitata dalla risoluzione del timer di sistema, e solo a partire dal
+kernel 2.6.21, con la implementazione delle temporizzazioni ad alta
+definizione, la risoluzione corrisponde a quella fornita dall'hardware
+disponibile.
+
+Una delle principali differenze della nuova interfaccia è che un processo può
+utilizzare un numero arbitrario di timer; questi vengono creati (ma non
+avviati) tramite la funzione \funcd{timer\_create}, il cui prototipo è:
+\begin{functions}
+ \headdecl{signal.h}
+ \headdecl{time.h}
+
+ \funcdecl{int timer\_create(clockid\_t clockid, struct sigevent *evp,
+ timer\_t *timerid)}
+
+ Crea un nuovo timer Posix.
+
+ \bodydesc{La funzione restituisce 0 in caso di successo e $-1$ in caso di
+ errore, nel qual caso \var{errno} assumerà uno dei valori già visti per
+ \func{sigwait}, ai quali si aggiunge, per \func{sigtimedwait}:
+ \begin{errlist}
+ \item[\errcode{EAGAIN}] fallimento nel tentativo di allocare le strutture
+ dei timer.
+ \item[\errcode{EINVAL}] uno dei valori specificati per \param{clockid} o per
+ i campi \var{sigev\_notify}, \var{sigev\_signo} o
+ \var{sigev\_notify\_thread\_id} di \param{evp} non è valido.
+ \item[\errcode{ENOMEM}] errore di allocazione della memoria.
+ \end{errlist}
+}
+\end{functions}
+
+La funzione richiede tre argomenti, il primo serve ad indicare quale tipo di
+orologio
+
+
+ fig.~\ref{fig:file_sigevent}
+
+\begin{figure}[!htb]
+ \footnotesize \centering
+ \begin{minipage}[c]{15cm}
+ \includestruct{listati/sigevent.h}
+ \end{minipage}
+ \normalsize
+ \caption{La struttura \structd{sigevent}, usata per specificare le modalità
+ di notifica degli eventi relativi alle operazioni di I/O asincrono.}
+ \label{fig:file_sigevent}
+\end{figure}
+
+
+
+
+
+% TODO trattare i Posix timer, e le fuzioni:
% timer_getoverrun, timer_gettime, timer_settime, timer_create, timer_delete
\subsection{Le interfacce per la notifica attraverso i file descriptor}
\label{sec:sig_signalfd_eventfd}
-
+
% TODO trattare qui eventfd signalfd e timerfd introdotte con il 2.6.22
% timerfd è stata tolta nel 2.6.23 e rifatta per bene nel 2.6.25
% LocalWords: INTDIV INTOVF FLTDIV FLTOVF FLTUND underflow FLTRES FLTINV SEGV
% LocalWords: FLTSUB MAPERR ACCERR ADRALN ADRERR OBJERR BRKPT CLD EXITED MSG
% LocalWords: KILLED DUMPED TRAPPED STOPPED CONTINUED PRI HUP SigFunc jiffies
-% LocalWords: SEC
+% LocalWords: SEC unsafe sockatmark execl execv faccessat fchmodat fchownat
+% LocalWords: fexecve fstatat futimens linkat mkdirat mkfifoat mknod mknodat
+% LocalWords: openat readlinkat renameat symlinkat unlinkat utimensat utimes
+% LocalWords: LinuxThread NTPL Library clockid evp timerid sigev notify high
+% LocalWords: resolution CONFIG RES patch REALTIME MONOTONIC RAW NTP CPUTIME
%%% Local Variables: