X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=blobdiff_plain;f=process.tex;h=601d3c3f513a6b601ec9e7fb1e3555b820c2b3d6;hp=8f8e6579af4b39de3ed0b1317c8e6721795f7dff;hb=6271cd1b0cc4d403753d1f48d3d562b16db7e613;hpb=ee41e8b34dd560d230966160fb3eb748defc3e46 diff --git a/process.tex b/process.tex index 8f8e657..601d3c3 100644 --- a/process.tex +++ b/process.tex @@ -151,13 +151,14 @@ non vengono salvati e le eventuali funzioni registrate con \func{atexit} e \bodydesc{La funzione non ritorna. Il processo viene terminato.} \end{prototype} -La funzione chiude tutti i file descriptor appartenenti al processo (si tenga +La funzione chiude tutti i file descriptor appartenenti al processo; si tenga presente che questo non comporta il salvataggio dei dati bufferizzati degli -stream), fa sì che ogni figlio del processo sia adottato da \cmd{init} (vedi -cap.~\ref{cha:process_handling}), manda un segnale \const{SIGCHLD} al processo -padre (vedi sez.~\ref{sec:sig_job_control}) ed infine ritorna lo stato di -uscita specificato in \param{status} che può essere raccolto usando la -funzione \func{wait} (vedi sez.~\ref{sec:proc_wait}). +stream, (torneremo sulle due interfacce dei file a partire da +cap.~\ref{cha:file_intro}), fa sì che ogni figlio del processo sia adottato da +\cmd{init} (vedi cap.~\ref{cha:process_handling}), manda un segnale +\const{SIGCHLD} al processo padre (vedi sez.~\ref{sec:sig_job_control}) ed +infine ritorna lo stato di uscita specificato in \param{status} che può essere +raccolto usando la funzione \func{wait} (vedi sez.~\ref{sec:proc_wait}). \subsection{Le funzioni \func{atexit} e \func{on\_exit}} @@ -182,7 +183,7 @@ che si pu Registra la funzione \param{function} per la chiamata all'uscita dal programma. - \bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di + \bodydesc{La funzione restituisce $0$ in caso di successo e $-1$ in caso di fallimento, \var{errno} non viene modificata.} \end{prototype} \noindent la funzione richiede come argomento l'indirizzo di una opportuna @@ -198,7 +199,7 @@ definita su altri sistemi; il suo prototipo Registra la funzione \param{function} per la chiamata all'uscita dal programma. - \bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di + \bodydesc{La funzione restituisce 0 in caso di successo e $-1$ in caso di fallimento, \var{errno} non viene modificata.} \end{prototype} @@ -645,7 +646,7 @@ causando a lungo andare un esaurimento della memoria disponibile (e la probabile impossibilità di proseguire l'esecuzione del programma). Il problema è che l'esaurimento della memoria può avvenire in qualunque -momento, in corrispondenza ad una qualunque chiamata di \func{malloc}, che può +momento, in corrispondenza ad una qualunque chiamata di \func{malloc} che può essere in una sezione del codice che non ha alcuna relazione con la subroutine che contiene l'errore. Per questo motivo è sempre molto difficile trovare un \itindex{memory~leak} \textit{memory leak}. @@ -688,7 +689,9 @@ 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 -molto complesse riguardo l'allocazione della memoria. +molto complesse riguardo l'allocazione della memoria. Vedremo alcune delle +funzionalità di ausilio presenti nelle \acr{glibc} in +sez.~\ref{sec:proc_memory_adv_management}. Una possibile alternativa all'uso di \func{malloc}, che non soffre dei problemi di \itindex{memory~leak} \textit{memory leak} descritti in @@ -761,7 +764,7 @@ ugiale di 500). La prima funzione \begin{prototype}{unistd.h}{int brk(void *end\_data\_segment)} Sposta la fine del segmento dei dati. - \bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di + \bodydesc{La funzione restituisce 0 in caso di successo e $-1$ in caso di fallimento, nel qual caso \var{errno} assumerà il valore \errval{ENOMEM}.} \end{prototype} @@ -842,6 +845,67 @@ motivi per cui si possono avere di queste necessit crittografia richiedono il blocco di alcune pagine di memoria. \end{itemize} +Per ottenere informazioni sulle modalità in cui un programma sta usando la +memoria virtuale è disponibile una apposita funzione, \funcd{mincore}, che +però non è standardizzata da POSIX e pertanto non è disponibile su tutte le +versioni di kernel unix-like;\footnote{nel caso di Linux devono essere + comunque definite le macro \macro{\_BSD\_SOURCE} e \macro{\_SVID\_SOURCE}.} +il suo prototipo è: +\begin{functions} + \headdecl{unistd.h} + \headdecl{sys/mman.h} + + \funcdecl{int mincore(void *addr, size\_t length, unsigned char *vec)} + Ritorna lo stato delle pagine di memoria occupate da un processo. + + \bodydesc{La funzione ritorna 0 in caso di successo e $-1$ in caso di + errore, nel qual caso \var{errno} assumerà uno dei valori seguenti: + \begin{errlist} + \item[\errcode{ENOMEM}] o \param{addr} + \param{lenght} eccede la dimensione + della memoria usata dal processo o l'intervallo di indirizzi specificato + non è mappato. + \item[\errcode{EINVAL}] \param{addr} non è un multiplo delle dimensioni di + una pagina. + \item[\errcode{EFAULT}] \param{vec} punta ad un indirizzo non valido. + \item[\errcode{EAGAIN}] il kernel è temporaneamente non in grado di fornire + una risposta. + \end{errlist} +} +\end{functions} + +La funzione permette di ottenere le informazioni sullo stato della mappatura +della memoria per il processo chiamante, specificando l'intervallo da +esaminare con l'indirizzo iniziale (indicato con l'argomento \param{addr}) e +la lunghezza (indicata con l'argomento \param{length}). L'indirizzo iniziale +deve essere un multiplo delle dimensioni di una pagina, mentre la lunghezza +può essere qualunque, fintanto che si resta nello spazio di indirizzi del +processo,\footnote{in caso contrario si avrà un errore di \errcode{ENOMEM}; + fino al kernel 2.6.11 in questo caso veniva invece restituito + \errcode{EINVAL}, in considerazione che il caso più comune in cui si + verifica questo errore è quando si usa per sbaglio un valore negativo + di \param{length}, che nel caso verrebbe interpretato come un intero + positivo di grandi dimensioni.} ma il risultato verrà comunque fornito per +l'intervallo compreso fino al multiplo successivo. + +I risultati della funzione vengono forniti nel vettore puntato da \param{vec}, +che deve essere allocato preventivamente e deve essere di dimensione +sufficiente a contenere tanti byte quante sono le pagine contenute +nell'intervallo di indirizzi specificato.\footnote{la dimensione cioè deve + essere almeno pari a \code{(length+PAGE\_SIZE-1)/PAGE\_SIZE}. } Al ritorno +della funzione il bit meno significativo di ciascun byte del vettore sarà +acceso se la pagina di memoria corrispondente è al momento residente in +memoria, o cancellato altrimenti. Il comportamento sugli altri bit è +indefinito, essendo questi al momento riservati per usi futuri. Per questo +motivo in genere è comunque opportuno inizializzare a zero il contenuto del +vettore, così che le pagine attualmente residenti in memoria saranno indicata +da un valore non nullo del byte corrispondente. + +Dato che lo stato della memoria di un processo può cambiare continuamente, il +risultato di \func{mincore} è assolutamente provvisorio e lo stato delle +pagine potrebbe essere già cambiato al ritorno stesso della funzione, a meno +che, come vedremo ora, non si sia attivato il meccanismo che forza il +mantenimento di una pagina sulla memoria. + \itindbeg{memory~locking} Il meccanismo che previene la \index{paginazione} paginazione di parte della @@ -882,7 +946,6 @@ standard POSIX.1 richiede che sia definita in \file{unistd.h} la macro in byte.\footnote{con Linux questo non avviene e si deve ricorrere alla funzione \func{getpagesize}, vedi sez.~\ref{sec:sys_memory_res}.} - A partire dal kernel 2.6.9 anche un processo normale può bloccare la propria memoria\footnote{la funzionalità è stata introdotta per non essere costretti a dare privilegi eccessivi a programmi di crittografia, che necessitano di @@ -906,7 +969,7 @@ prototipi sono: \funcdecl{int munlock(const void *addr, size\_t len)} Rimuove il blocco della paginazione su un intervallo di memoria. - \bodydesc{Entrambe le funzioni ritornano 0 in caso di successo e -1 in + \bodydesc{Entrambe le funzioni ritornano 0 in caso di successo e $-1$ in caso di errore, nel qual caso \var{errno} assumerà uno dei valori seguenti: \begin{errlist} @@ -984,23 +1047,196 @@ ci si scrive sopra. \itindend{memory~locking} +\index{memoria~virtuale|)} -% TODO documentare \func{madvise} -% TODO documentare \func{mincore} +\subsection{Gestione avanzata dell'allocazione della memoria} +\label{sec:proc_memory_adv_management} + +La trattazione delle funzioni di allocazione di sez.~\ref{sec:proc_mem_alloc} +si è limitata a coprire le esigenze generiche di un programma, in cui non si +hanno dei requisiti specifici e si lascia il controllo delle modalità di +allocazione alle funzioni di libreria. Tuttavia esistono una serie di casi in +cui può essere necessario avere un controllo più dettagliato delle modalità +con cui la memoria viene allocata; nel qual caso potranno venire in aiuto le +funzioni trattate in questa sezione. + +Le prime funzioni che tratteremo sono quelle che consentono di richiedere di +allocare un blocco di memoria ``\textsl{allineato}'' ad un multiplo una certa +dimensione. Questo tipo di esigenza emerge usualmente quando si devono +allocare dei buffer da utilizzare per eseguire dell'I/O diretto su dispositivi +a blocchi. In questo caso infatti il trasferimento di dati viene eseguito per +blocchi di dimensione fissa, ed è richiesto che l'indirizzo di partenza del +buffer sia un multiplo intero di questa dimensione, usualmente 512 byte. In +tal caso l'uso di \func{malloc} non è sufficiente, ed occorre utilizzare una +funzione specifica. + +Tradizionalmente per rispondere a questa esigenza sono state crate due +funzioni diverse, \funcd{memalign} e \funcd{valloc}, oggi obsolete; i +rispettivi prototipi sono: +\begin{functions} + \headdecl{malloc.h} -\index{memoria~virtuale|)} + \funcdecl{void *valloc(size\_t size)} Alloca un blocco di memoria allineato + alla dimensione di una pagina di memoria. + + \funcdecl{void *memalign(size\_t boundary, size\_t size)} + Alloca un blocco di memoria allineato ad un multiplo di \param{boundary}. + + \bodydesc{Entrambe le funzioni ritornano un puntatore al blocco di memoria + allocato in caso di successo e \val{NULL} in caso di errore, nel qual + caso \var{errno} assumerà uno dei valori seguenti: + \begin{errlist} + \item[\errcode{ENOMEM}] non c'è memoria sufficiente per l'allocazione. + \item[\errcode{EINVAL}] \param{boundary} non è multiplo di due. + \end{errlist} +} +\end{functions} +Le funzioni restituiscono il puntatore al buffer di memoria allocata, che per +\func{memalign} sarà un multiplo di \param{boundary} mentre per \func{valloc} +un multiplo della dimensione di una pagina di memoria. Nel caso della versione +fornita dalle \acr{glibc} la memoria allocata con queste funzioni deve essere +liberata con \func{free}, cosa che non è detto accada con altre +implementazioni. + +Nessuna delle due funzioni ha una chiara standardizzazione (nessuna delle due +compare in POSIX.1), ed inoltre ci sono indicazioni discordi sui file che ne +contengono la definizione;\footnote{secondo SUSv2 \func{valloc} è definita in + \texttt{stdlib.h}, mentre sia le \acr{glibc} che le precedenti \acr{libc4} e + \acr{lic5} la dichiarano in \texttt{malloc.h}, lo stesso vale per + \func{memalign} che in alcuni sistemi è dichiarata in \texttt{stdlib.h}.} +per questo motivo il loro uso è sconsigliato, essendo state sostituite dalla +nuova \funcd{posix\_memalign}, che è stata standardizzata in POSIX.1d; il suo +prototipo è: +\begin{prototype}{stdlib.h}{posix\_memalign(void **memptr, size\_t alignment, + size\_t size) } + Alloca un buffer di memoria allineato ad un multiplo di \param{alignment}. + + \bodydesc{La funzione restituisce 0 in caso di successo e \val{NULL} in caso + di fallimento, o uno dei due codici di errore \errcode{ENOMEM} o + \errcode{EINVAL}; \var{errno} non viene impostata.} +\end{prototype} -% \subsection{Gestione avanzata dell'allocazione della memoria} -% \label{sec:proc_mem_malloc_custom} +La funzione restituisce il puntatore al buffer allocato all'indirizzo indicato +da \param{memptr}. La funzione fallisce nelle stesse condizioni delle due +funzioni precedenti, ma a differenza di \func{memalign} restituisce un codice +di errore \errcode{EINVAL} anche se \param{alignment} non è un multiplo della +la dimensione di \code{sizeof(void *)}. Come per le precedenti la memoria +allocata con \func{posix\_memalign} può essere disallocata con +\func{free}.\footnote{che in questo caso è quanto richiesto dallo standard.} + +Un secondo caso in cui risulta estremamente utile poter avere un maggior +controllo delle modalità di allocazione della memoria è quello in cui cercano +errori di programmazione. Esempi di questi errori sono chiamate doppie alla +funzione \func{free} con lo stesso puntatore, o i cosiddetti +\itindex{buffer~overrun} \textit{buffer overrun}, cioè le scritture su un buffer +oltre le dimensioni della sua allocazione,\footnote{entrambe queste operazioni + causano in genere la corruzione dei dati di controllo delle funzioni di + allocazione, che vengono anch'essi mantenuti nello \itindex{heap} + \textit{heap} per tenere traccia delle zone di memoria allocata.} o i +classici \itindex{memory~leak} \textit{memory leak}. + +Una prima funzionalità di ausilio nella ricerca di questi errori viene fornita +dalla \acr{glibc} tramite l'uso della variabile di ambiente (vedi +sez.~\ref{sec:proc_environ}) \var{MALLOC\_CHECK\_}. Quando questa viene +definita al posto della versione ordinaria delle funzioni di allocazione +(\func{malloc}, \func{calloc}, \func{realloc}, e \func{free}) viene usata una +versione meno efficiente ma in grado di rilevare (e tollerare) alcuni degli +errori più semplici, come le doppie chiamate a \func{free} o i +\itindex{buffer~overrun} \textit{buffer overrun} di un byte.\footnote{uno + degli errori più comuni, causato ad esempio dalla scrittura di una stringa + di dimensione pari a quella del buffer, in cui ci si dimentica dello zero di + terminazione finale.} + +In questo caso a seconda del valore assegnato a \var{MALLOC\_CHECK\_} si +avranno diversi comportamenti: con 0 l'errore sarà ignorato, con 1 verrà +stampato un messaggio sullo \textit{standard error} (vedi +sez.~\ref{sec:file_std_stream}), con 2 verrà invocata la funzione \func{abort} +(vedi sez.~\ref{sec:sig_alarm_abort}) che termina il programma, con 3 viene +sia stampato il messaggio d'errore che abortito il programma. In genere è +opportuno definire la variabile ad un valore diverso da zero che consente di +rilevare un errore nel momento in cui avviene. + +Una modalità alternativa per effettuare dei controlli di consistenza sullo +stato delle allocazioni di memoria eseguite con \func{malloc}, anche questa +fornita come estensione specifica (e non standard) delle \acr{glibc}, è quella +di utilizzare la funzione \funcd{mcheck}, che deve essere chiamata prima di +eseguire qualunque allocazione con \func{malloc}; il suo prototipo è: +\begin{prototype}{mcheck.h}{mcheck(void (*abortfn) (enum mcheck\_status + status))} + Attiva i controlli di consistenza delle allocazioni eseguite da \func{malloc}. + + \bodydesc{La funzione restituisce 0 in caso di successo e $-1$ in caso di + fallimento; \var{errno} non viene impostata.} +\end{prototype} -% TODO: trattare le funzionalità avanzate di \func{malloc} -% TODO: trattare \func{memalign} -% TODO: trattare \func{valloc} -% TODO: trattare \func{posix\_memalign} +La funzione consente di registrare una funzione di emergenza, da passare come +argomento, che verrà eseguita tutte le volte che, in una successiva esecuzione +di \func{malloc}, venissero trovate delle inconsistenze, come delle operazioni +di scrittura oltre i limiti dei buffer allocati. Per questo motivo la funzione +deve essere chiamata prima di qualunque allocazione di memoria, altrimenti +fallirà con un valore di ritorno pari a $-1$. + +Se come argomento di \func{mcheck} si passa \var{NULL} verrà utilizzata una +funzione predefinita che stampa un messaggio di errore ed invoca la funzione +\func{abort} (vedi sez.~\ref{sec:sig_alarm_abort}), altrimenti si dovrà create +una funzione personalizzata che verrà eseguita ricevendo un unico argomento di +tipo \type{mcheck\_status},\footnote{trattasi in sostanza di un codice di + errore che la funzione di emergenza potrà utilizzare per prendere le + opportune azioni.} un tipo enumerato che può assumere soltanto i valori di +tab.~\ref{tab:mcheck_status_value}. +\begin{table}[htb] + \centering + \footnotesize + \begin{tabular}[c]{|l|p{7cm}|} + \hline + \textbf{Valore} & \textbf{Significato} \\ + \hline + \hline + \macro{MCHECK\_OK} & riportato (a \func{mprobe}) se nessuna + inconsistenza è presente.\\ + \macro{MCHECK\_DISABLED}& riportato (a \func{mprobe}) se si è chiamata + \func{mcheck} dopo aver già usato + \func{malloc}.\\ + \macro{MCHECK\_HEAD} & i dati immediatamente precedenti il buffer sono + stati modificati, avviene in genere quando si + decrementa eccessivamente il valore di un + puntatore scrivendo poi prima dell'inizio del + buffer.\\ + \macro{MCHECK\_TAIL} & i dati immediatamente seguenti il buffer sono + stati modificati, succede quando si va scrivere + oltre la dimensione correttta del buffer.\\ + \macro{MCHECK\_FREE} & il buffer è già stato disallocato.\\ + \hline + \end{tabular} + \caption{Valori dello stato dell'allocazione di memoria ottenibili dalla + funzione di teminazione installata con \func{mcheck}.} + \label{tab:mcheck_status_value} +\end{table} +Una volta che si sia chiamata \func{mcheck} con successo si può anche +controllare esplicitamente lo stato delle allocazioni (senza aspettare un +errore nelle relative funzioni) utilizzando la funzione \funcd{mprobe}, il cui +prototipo è: +\begin{prototype}{mcheck.h}{enum mcheck\_status mprobe(ptr)} + Esegue un controllo di consistenza delle allocazioni. + + \bodydesc{La funzione restituisce un codice fra quelli riportati in + tab.\ref{tab:mcheck_status_value}.} +\end{prototype} + +La funzione richiede che si passi come argomento un puntatore ad un blocco di +memoria precedentemente allocato con \func{malloc} o \func{realloc}, e +restituisce lo stesso codice di errore che si avrebbe per la funzione di +emergenza ad una successiva chiamata di una funzione di allocazione, e poi i +primi due codici che indicano rispettivamente quando tutto è a posto o il +controllo non è possibile per non aver chiamato \func{mcheck} in tempo. + +% TODO: trattare le altre funzionalità avanzate di \func{malloc}, mallopt, +% mtrace, muntrace, mallinfo e gli hook con le glibc 2.10 c'è pure malloc_info +% a sostituire mallinfo, vedi http://udrepper.livejournal.com/20948.html \section{Argomenti, opzioni ed ambiente di un processo} \label{sec:proc_options} @@ -1023,13 +1259,13 @@ manipolare ed utilizzare le variabili di ambiente. \subsection{Il formato degli argomenti} \label{sec:proc_par_format} -In genere il passaggio degli argomenti al programma viene effettuato dalla +In genere il passaggio degli argomenti ad un programma viene effettuato dalla shell, che si incarica di leggere la linea di comando e di effettuarne la scansione (il cosiddetto \textit{parsing}) per individuare le parole che la compongono, ciascuna delle quali viene considerata un argomento. Di norma per -individuare le parole viene usato come carattere di separazione lo spazio o il -tabulatore, ma il comportamento è modificabile attraverso l'impostazione della -variabile di ambiente \cmd{IFS}. +individuare le parole che andranno a costituire la lista degli argomenti viene +usato come carattere di separazione lo spazio o il tabulatore, ma la cosa +dipende ovviamente dalle modalità con cui si effettua il lancio. \begin{figure}[htb] \centering @@ -1039,11 +1275,13 @@ variabile di ambiente \cmd{IFS}. \label{fig:proc_argv_argc} \end{figure} -Nella scansione viene costruito il vettore di puntatori \param{argv} inserendo -in successione il puntatore alla stringa costituente l'$n$-simo argomento; la -variabile \param{argc} viene inizializzata al numero di argomenti trovati, in -questo modo il primo argomento è sempre il nome del programma; un esempio di -questo meccanismo è mostrato in fig.~\ref{fig:proc_argv_argc}. +Indipendentemente da come viene eseguita, il risultato della scansione deve +essere la costruzione del vettore di puntatori \param{argv} in cui si devono +inserire in successione i puntatori alle stringhe costituenti i vari +argomenti, e della variabile \param{argc} che deve essere inizializzata al +numero di argomenti trovati. Nel caso della shell questo comporta che il primo +argomento sia sempre il nome del programma; un esempio di questo meccanismo è +mostrato in fig.~\ref{fig:proc_argv_argc}. \subsection{La gestione delle opzioni} @@ -1069,7 +1307,7 @@ Esegue il parsing degli argomenti passati da linea di comando riconoscendo le possibili opzioni segnalate con \param{optstring}. \bodydesc{Ritorna il carattere che segue l'opzione, \cmd{':'} se manca un - parametro all'opzione, \cmd{'?'} se l'opzione è sconosciuta, e -1 se non + parametro all'opzione, \cmd{'?'} se l'opzione è sconosciuta, e $-1$ se non esistono altre opzioni.} \end{prototype} @@ -1086,7 +1324,7 @@ due punti \texttt{':'}; nel caso di fig.~\ref{fig:proc_argv_argc} ad esempio la stringa di opzioni avrebbe dovuto contenere \texttt{"r:m"}. La modalità di uso di \func{getopt} è pertanto quella di chiamare più volte la -funzione all'interno di un ciclo, fintanto che essa non ritorna il valore -1 +funzione all'interno di un ciclo, fintanto che essa non ritorna il valore $-1$ che indica che non ci sono più opzioni. Nel caso si incontri un'opzione non dichiarata in \param{optstring} viene ritornato il carattere \texttt{'?'} mentre se un'opzione che lo richiede non è seguita da un parametro viene @@ -1297,7 +1535,7 @@ ambiente, i loro prototipi sono i seguenti: \funcdecl{int putenv(char *string)} Aggiunge la stringa \param{string} all'ambiente. - \bodydesc{Entrambe le funzioni ritornano 0 in caso di successo e -1 per un + \bodydesc{Entrambe le funzioni ritornano 0 in caso di successo e $-1$ per un errore, che è sempre \errval{ENOMEM}.} \end{functions} \noindent la terza, \funcd{unsetenv}, serve a cancellare una variabile di @@ -1368,20 +1606,18 @@ alla cancellazione di tutto l'ambiente per costruirne una versione ``\textsl{sicura}'' da zero. -\subsection{Opzioni in formato esteso} -\label{sec:proc_opt_extended} - -Oltre alla modalità ordinaria di gestione delle opzioni trattata in -sez.~\ref{sec:proc_opt_handling} le \acr{glibc} forniscono una modalità -alternativa costituita dalle cosiddette \textit{long-options}, che consente di -esprimere le opzioni in una forma più descrittiva che nel caso più generale è -qualcosa del tipo di ``\texttt{-{}-option-name=parameter}''. - -(NdA: questa parte verrà inserita in seguito). +%\subsection{Opzioni in formato esteso} +%\label{sec:proc_opt_extended} -% TODO opzioni in formato esteso +%Oltre alla modalità ordinaria di gestione delle opzioni trattata in +%sez.~\ref{sec:proc_opt_handling} le \acr{glibc} forniscono una modalità +%alternativa costituita dalle cosiddette \textit{long-options}, che consente di +%esprimere le opzioni in una forma più descrittiva che nel caso più generale è +%qualcosa del tipo di ``\texttt{-{}-option-name=parameter}''. +%(NdA: questa parte verrà inserita in seguito). +% TODO opzioni in formato esteso \section{Problematiche di programmazione generica} \label{sec:proc_gen_prog}