Un semplice esempio dell'uso di queste funzioni è riportato in
fig.~\ref{fig:file_my_ls}, dove si è riportata la sezione principale di un
-programma che, usando la routine di scansione illustrata in
+programma che, usando la funzione di scansione illustrata in
fig.~\ref{fig:file_dirscan}, stampa i nomi dei file contenuti in una directory
e la relativa dimensione (in sostanza una versione semplificata del comando
\cmd{ls}).
\begin{minipage}[c]{15.6cm}
\includecodesample{listati/DirScan.c}
\end{minipage}
- \caption{Codice della routine di scansione di una directory contenuta nel
+ \caption{Codice della funzione di scansione di una directory contenuta nel
file \file{DirScan.c}.}
\label{fig:file_dirscan}
\end{figure}
Quando un processo esegue una system call che opera su un file, il kernel
chiama sempre una funzione implementata nel VFS; la funzione eseguirà le
manipolazioni sulle strutture generiche e utilizzerà poi la chiamata alle
-opportune routine del filesystem specifico a cui si fa riferimento. Saranno
+opportune funzioni del filesystem specifico a cui si fa riferimento. Saranno
queste a chiamare le funzioni di più basso livello che eseguono le operazioni
di I/O sul dispositivo fisico, secondo lo schema riportato in
fig.~\ref{fig:file_VFS_scheme}.
nelle operazioni di montaggio. Quest'ultima è responsabile di leggere da disco
il superblock (vedi sez.~\ref{sec:file_ext2}), inizializzare tutte le variabili
interne e restituire uno speciale descrittore dei filesystem montati al VFS;
-attraverso quest'ultimo diventa possibile accedere alle routine specifiche per
+attraverso quest'ultimo diventa possibile accedere alle funzioni specifiche per
l'uso di quel filesystem.
Il primo oggetto usato dal VFS è il descrittore di filesystem, un puntatore ad
ogni filesystem, i dati privati relativi a quel filesystem specifico, e i
puntatori alle funzioni del kernel relative al filesystem. Il VFS può così
usare le funzioni contenute nel \textit{filesystem descriptor} per accedere
-alle routine specifiche di quel filesystem.
+alle funzioni specifiche di quel filesystem.
Gli altri due descrittori usati dal VFS sono relativi agli altri due oggetti
su cui è strutturata l'interfaccia. Ciascuno di essi contiene le informazioni
In questo modo per ciascun file diventano possibili una serie di operazioni
(non è detto che tutte siano disponibili), che costituiscono l'interfaccia
astratta del VFS. Qualora se ne voglia eseguire una, il kernel andrà ad
-utilizzare l'opportuna routine dichiarata in \struct{f\_ops} appropriata al
+utilizzare l'opportuna funzione dichiarata in \struct{f\_ops} appropriata al
tipo di file in questione.
Pertanto è possibile scrivere allo stesso modo sulla porta seriale come su un
\bodydesc{Le funzioni ritornano il numero di caratteri stampati.}
\end{functions}
\noindent con queste funzioni diventa possibile selezionare gli argomenti che
-si vogliono passare ad una routine di stampa, passando direttamente la lista
+si vogliono passare ad una funzione di stampa, passando direttamente la lista
tramite l'argomento \param{ap}. Per poter far questo ovviamente la lista degli
argomenti dovrà essere opportunamente trattata (l'argomento è esaminato in
sez.~\ref{sec:proc_variadic}), e dopo l'esecuzione della funzione l'argomento
dell'insieme delle frasi non nulla, dato che l'inizializzazione del vettore
\var{fortune} avviene solo quando questa dimensione viene specificata, la
presenza di un valore nullo provoca l'uscita dal programma attraverso la
-routine (non riportata) che ne stampa le modalità d'uso. Dopo di che installa
-(\texttt{\small 13--15}) la funzione che gestisce i segnali di interruzione
-(anche questa non è riportata in fig.~\ref{fig:ipc_fifo_server}) che si limita
-a rimuovere dal filesystem la fifo usata dal server per comunicare.
+funzione (non riportata) che ne stampa le modalità d'uso. Dopo di che
+installa (\texttt{\small 13--15}) la funzione che gestisce i segnali di
+interruzione (anche questa non è riportata in fig.~\ref{fig:ipc_fifo_server})
+che si limita a rimuovere dal filesystem la fifo usata dal server per
+comunicare.
Terminata l'inizializzazione (\texttt{\small 16}) si effettua la chiamata alla
funzione \code{FortuneParse} che legge dal file specificato in
A questo punto si può entrare nel ciclo principale del programma che fornisce
le risposte ai client (\texttt{\small 34--50}); questo viene eseguito
indefinitamente (l'uscita del server viene effettuata inviando un segnale, in
-modo da passare attraverso la routine di chiusura che cancella la fifo).
+modo da passare attraverso la funzione di chiusura che cancella la fifo).
Il server è progettato per accettare come richieste dai client delle stringhe
che contengono il nome della fifo sulla quale deve essere inviata la risposta.
e senza ulteriori \file{/}, Linux supporta comunque nomi generici, che
verranno intepretati prendendo come radice \file{/dev/shm}.\footnote{occorre
pertanto evitare di specificare qualcosa del tipo \file{/dev/shm/nome}
- all'interno di \param{name}, perché questo comporta, da parte delle routine
+ all'interno di \param{name}, perché questo comporta, da parte delle funzioni
di libereria, il tentativo di accedere a \file{/dev/shm/dev/shm/nome}.}
La funzione è del tutto analoga ad \func{open} ed analoghi sono i valori che
\subsection{La funzione \func{main}}
\label{sec:proc_main}
-Quando un programma viene lanciato il kernel esegue un'opportuna routine di
+Quando un programma viene lanciato il kernel esegue un opportuno codice di
avvio, usando il programma \cmd{ld-linux.so}. Questo programma prima carica
le librerie condivise che servono al programma, poi effettua il collegamento
dinamico del codice e alla fine lo esegue. Infatti, a meno di non aver
direttamente la funzione \func{exit} (che viene comunque chiamata
automaticamente quando \func{main} ritorna). Una forma alternativa è quella
di chiamare direttamente la system call \func{\_exit}, che restituisce il
-controllo direttamente alla routine di conclusione dei processi del kernel.
+controllo direttamente alla funzione di conclusione dei processi del kernel.
Oltre alla conclusione ``\textsl{normale}'' esiste anche la possibilità di una
conclusione ``\textsl{anomala}'' del programma a causa della ricezione di un
che, quando l'argomento è un puntatore nullo, \func{free} non esegue nessuna
operazione.
-Le \acr{glibc} hanno un'implementazione delle routine di allocazione che è
+Le \acr{glibc} hanno un'implementazione delle funzioni di allocazione che è
controllabile dall'utente attraverso alcune variabili di ambiente, in
particolare diventa possibile tracciare questo tipo di errori usando la
variabile di ambiente \val{MALLOC\_CHECK\_} che quando viene definita mette in
\end{itemize}
Il problema più comune e più difficile da risolvere che si incontra con le
-routine di allocazione è quando non viene opportunamente liberata la memoria
+funzioni di allocazione è quando non viene opportunamente liberata la memoria
non più utilizzata, quello che in inglese viene chiamato \textit{memory
leak}\itindex{memory~leak}, cioè una \textsl{perdita di memoria}.
% allocata da un oggetto.
Per limitare l'impatto di questi problemi, e semplificare la ricerca di
-eventuali errori, l'implementazione delle routine di allocazione delle
+eventuali errori, l'implementazione delle funzioni di allocazione delle
\acr{glibc} mette a disposizione una serie di funzionalità che permettono di
tracciare le allocazioni e le disallocazioni, e definisce anche una serie di
possibili \textit{hook} (\textsl{ganci}) che permettono di sostituire alle
funzioni di libreria una propria versione (che può essere più o meno
specializzata per il debugging). Esistono varie librerie che forniscono dei
-sostituti opportuni delle routine di allocazione in grado, senza neanche
+sostituti opportuni delle funzioni di allocazione in grado, senza neanche
ricompilare il programma,\footnote{esempi sono \textit{Dmalloc}
\href{http://dmalloc.com/}{\textsf{http://dmalloc.com/}} di Gray Watson ed
\textit{Electric Fence} di Bruce Perens.} di eseguire diagnostiche anche
esplicitamente escluse dallo standard POSIX.} vengono utilizzate soltanto
quando è necessario effettuare direttamente la gestione della memoria
associata allo spazio dati di un processo, ad esempio qualora si debba
-implementare la propria versione delle routine di allocazione della memoria
+implementare la propria versione delle funzioni di allocazione della memoria
viste in sez.~\ref{sec:proc_mem_malloc}. La prima funzione è \funcd{brk}, ed
il suo prototipo è:
\begin{prototype}{unistd.h}{int brk(void *end\_data\_segment)}
Il passaggio di una variabile \textit{by value} significa che in realtà quello
che viene passato alla subroutine è una copia del valore attuale di quella
variabile, copia che la subroutine potrà modificare a piacere, senza che il
-valore originale nella routine chiamante venga toccato. In questo modo non
+valore originale nella funzione chiamante venga toccato. In questo modo non
occorre preoccuparsi di eventuali effetti delle operazioni della subroutine
sulla variabile passata come argomento.
subroutine si usano dei puntatori (ad esempio per scrivere in un buffer) in
realtà si va a modificare la zona di memoria a cui essi puntano, per cui anche
se i puntatori sono copie, i dati a cui essi puntano sono sempre gli stessi, e
-le eventuali modifiche avranno effetto e saranno visibili anche nella routine
+le eventuali modifiche avranno effetto e saranno visibili anche nella funzione
chiamante.
Nella maggior parte delle funzioni di libreria e delle system call i puntatori
vengono usati per scambiare dati (attraverso buffer o strutture) e le
variabili semplici vengono usate per specificare argomenti; in genere le
-informazioni a riguardo dei risultati vengono passate alla routine chiamante
+informazioni a riguardo dei risultati vengono passate alla funzione chiamante
attraverso il valore di ritorno. È buona norma seguire questa pratica anche
nella programmazione normale.
diverso da zero viene restituito solo quando il ritorno è dovuto ad una
chiamata di \func{longjmp} in un'altra parte del programma che ripristina lo
\itindex{stack} stack effettuando il salto non-locale. Si tenga conto che il
-contesto salvato in \param{env} viene invalidato se la routine che ha chiamato
-\func{setjmp} ritorna, nel qual caso un successivo uso di \func{longjmp} può
-comportare conseguenze imprevedibili (e di norma fatali) per il processo.
+contesto salvato in \param{env} viene invalidato se la funzione che ha
+chiamato \func{setjmp} ritorna, nel qual caso un successivo uso di
+\func{longjmp} può comportare conseguenze imprevedibili (e di norma fatali)
+per il processo.
Come accennato per effettuare un salto non-locale ad
un punto precedentemente stabilito con \func{setjmp} si usa la funzione
\bodydesc{La funzione restituisce il precedente valore.}
\end{prototype}
-Le routine di gestione mantengono per ogni processo una maschera che determina
+Le funzioni di gestione mantengono per ogni processo una maschera che determina
quale delle chiamate effettuate a \func{syslog} verrà effettivamente
registrata. La registrazione viene disabilitata per tutte quelle priorità che
non rientrano nella maschera; questa viene impostata usando la macro
kernel che causa la generazione di un particolare tipo di segnale.
Quando un processo riceve un segnale, invece del normale corso del programma,
-viene eseguita una azione predefinita o una apposita routine di gestione
+viene eseguita una azione predefinita o una apposita funzione di gestione
(quello che da qui in avanti chiameremo il \textsl{gestore} del segnale,
dall'inglese \textit{signal handler}) che può essere stata specificata
dall'utente (nel qual caso si dice che si \textsl{intercetta} il segnale).
\textit{unreliable}).
Nella \textsl{semantica inaffidabile} (quella implementata dalle prime
-versioni di Unix) la routine di gestione del segnale specificata dall'utente
+versioni di Unix) la funzione di gestione del segnale specificata dall'utente
non resta attiva una volta che è stata eseguita; è perciò compito dell'utente
stesso ripetere l'installazione all'interno del \textsl{gestore} del segnale,
in tutti quei casi in cui si vuole che esso resti attivo.
la formazione di zombie\index{zombie}.
In fig.~\ref{fig:sig_sigchld_handl} è mostrato il codice contenente una
-implementazione generica di una routine di gestione per \const{SIGCHLD}, (che
+implementazione generica di una funzione di gestione per \const{SIGCHLD}, (che
si trova nei sorgenti allegati nel file \file{SigHand.c}); se ripetiamo i test
di sez.~\ref{sec:proc_termination}, invocando \cmd{forktest} con l'opzione
\cmd{-s} (che si limita ad effettuare l'installazione di questa funzione come
sez.~\ref{sec:sys_user_group} per le corrispondenze fra nomi di utenti e
gruppi e relativi identificatori numerici; per quanto riguarda però tutti i
nomi associati a identificativi o servizi relativi alla rete il servizio di
-risoluzione è gestito in maniera unificata da un insieme di routine fornite
+risoluzione è gestito in maniera unificata da un insieme di funzioni fornite
con le librerie del C, detto appunto \textit{resolver}.
Lo schema di funzionamento del \textit{resolver} è illustrato in
I \textit{packet socket}, identificati dal dominio \const{PF\_PACKET}, sono
un'interfaccia specifica di Linux per inviare e ricevere pacchetti
-direttamente su un'interfaccia di rete, senza passare per le routine di
+direttamente su un'interfaccia di rete, senza passare per le funzioni di
gestione dei protocolli di livello superiore. In questo modo è possibile
implementare dei protocolli in user space, agendo direttamente sul livello
fisico. In genere comunque si preferisce usare la libreria \file{pcap}, che