Poche aggiunte
[gapil.git] / process.tex
1 \chapter{L'interfaccia base con i processi}
2 \label{cha:process_interface}
3
4 Come accennato nell'introduzione il processo è l'unità di base con cui un
5 sistema unix alloca ed utilizza le risorse.  Questo capitolo tratterà
6 l'interfaccia base fra il sistema e i processi, su come vengono passati i
7 parametri, come viene gestita e allocata la memoria, su come un processo può
8 richiedere servizi al sistema, su cosa deve fare quando ha finito la sua
9 esecuzione.
10
11 In genere un programma viene eseguito quando un processo lo fa partire
12 eseguendo una funzione della famiglia \texttt{exec}; torneremo su questo e
13 sulla la creazione e gestione dei processi nel prossimo capitolo, in questo
14 affronteremo l'avvio e il funzionamento di un programma dal punto di vista del
15 programma posto in esecuzione.
16
17
18 \section{Esecuzione e conclusione di un programma}
19
20 Una delle concetti base relativi ai processi è che un processo esegue sempre
21 uno ed un solo programma: si possono avere più processi che eseguono lo stesso
22 programma ma ciascun processo vedrà la sua copia del codice (in realtà il
23 kernel fa si che tutte le parti uguali siano condivise) avrà un suo spazio di
24 indirizzi, variabili proprie e sarà eseguito in maniera completamente
25 indipendente da tutti gli altri. 
26
27 Anche quando all'interno di un programma possono essere presenti più
28 \textsl{filoni} di esecuzione (i cosiddetti \textit{thread}), o questo possa
29 essere composto da moduli multipli completamente separati, quando questo sarà
30 posto in esecuzione esso apparirà al sistema come un solo processo (il
31 discorso dei \textit{thread} comunque in linux necessita di una trattazione a
32 parte per la peculiarità dell'implementazione).
33
34
35 \section{La funzione \texttt{main}} 
36 \label{sec:proc_main}
37
38 Quando un programma viene lanciato dal kernel viene eseguito il
39 programma \texttt{ld-linux.so}, è questo programma che prima carica le
40 librerie condivise che servono al programma, effettua il link dinamico del
41 codice e poi alla fine lo esegue. La procedura è controllata da alcune
42 variabili di ambiente e dai settaggi di 
43
44 Il sistema fa partire qualunque programma chiamando la funzione \texttt{main};
45 sta al programmatore chiamare così la funzione principale del programma, se
46 così non fosse lo stesso linker darebbe luogo ad errori.
47
48 Lo stadard ISO C specifica che detta funzione può non avere argomenti o
49 prendere due argomenti che rappresentano gli argomenti passati da linea di
50 comando, in sostanza un prototipo che va sempre bene è il seguente:
51 \begin{verbatim}
52      int main (int argc, char *argv[])
53 \end{verbatim}
54
55
56 In realtà nei sistemi unix esiste un'altro modo per definire la funzione
57 \texttt{main}, che prende un terzo parametro, \texttt{char *envp[]}, che
58 fornisce l'ambiente (vedi \secref{proc_environ}) del programma; questa forma
59 però non è prevista dallo standard POSIX.1 per cui se si vogliono scrivere
60 programmi portabili è meglio evitarla.
61
62
63
64 \subsection{}
65 \label{sec:proc_}
66
67
68
69 \subsection{La funzione \texttt{exit}}
70 \label{sec:proc_exit}
71
72
73 \section{La gestione della memoria}
74 \label{sec:proc_mem_manag}
75
76
77
78 \section{Gestione di parametri e opzioni}
79 \label{sec:parameter_options}
80
81 Il passaggio dei parametri e delle variabili di ambiente dalla riga di comando
82 al singolo programma quando viene lanciato è effettuato attraverso le
83 variabili \texttt{argc}, \texttt{argv} che vengono passate al programma
84 come argomenti della funzione principale.
85
86 \subsection{Il formato dei parametri}
87 \label{sec:proc_par_format}
88 In genere passaggio dei parametri al programma viene effettuato dalla shell,
89 che si incarica di leggere la linea di comando e di effettuarne la scansione
90 (il cosiddetto \textit{parsing}) per individuare le parole che la compongono,
91 ciascuna delle quali viene considerata un parametro; di default per
92 individuare le parole viene usato come separatore lo spazio (comportamento
93 modificabile attraverso il settaggio della variabile di ambiente IFS).
94
95 Nella scansione viene costruito l'array di puntatori \texttt{argv} inserendo
96 in successione il puntatore alla stringa costituente l'$n$-simo parametro; la
97 variabile \texttt{argc} viene inizializzata al numero di parametri trovati, in
98 questo modo il primo parametro è sempre il nome del programma (vedi \nfig).
99
100 \subsection{La gestione delle opzioni}
101 \label{sec:proc_opt_handling}
102
103 In generale un programma unix riceve da linea di comando sia i parametri che
104 le opzioni, queste ultime sono standardizzate per essere riconosciute come
105 tali: un elemento di \texttt{argv} che inizia con \texttt{-} e che non sia un
106 singolo \texttt{-} o \texttt{--} viene considerato un'opzione.  In in genere
107 le opzioni sono costituite da un lettera preceduta dal meno e possono avere o
108 no un parametro associato; un comando tipico può essere cioè qualcosa del
109 tipo:
110 \begin{verbatim}
111 touch -r riferimento.txt -m questofile.txt
112 \end{verbatim}
113 ed in questo caso le opzioni sono \texttt{m} ed \texttt{r}.
114
115 Per gestire le opzioni all'interno dei parametri passati in \texttt{argv} le
116 librerie standard del C forniscono la funzione \texttt{getopt} (accessibile
117 includendo \texttt{unistd.h}), che ha il prototipo:
118 \begin{verbatim}
119 int getopt(int argc, char * const argv[], const char * optstring);
120 \end{verbatim}
121
122 Questa funzione prende come argomenti le due variabili \texttt{argc} e
123 \texttt{argv} ed una stringa che indica quali sono le opzioni valide; la
124 funzione effettua la scansione della lista dei parametri ricercando ogni
125 stringa che comincia con \texttt{-} e ritorna ogni volta che trova una opzione
126 valida.
127
128 La stringa \texttt{optstring} indica quali sono le opzioni riconosciute ed è
129 costituita da tutti i caratteri usati per identificare le singole opzioni, se
130 l'opzione ha un parametro al carattere deve essere fatto seguire un segno di
131 due punti \texttt{:} nel caso appena accennato ad esempio la stringa di
132 opzioni sarebbe \texttt{"r:m"}.
133
134 La modalità di uso è pertanto quella di chiamare più volte la funzione
135 all'interno di un ciclo di while fintanto che essa non ritorna il valore
136 \texttt{-1} che indica che non ci sono più opzioni. Nel caso si incontri
137 un'opzione non dichiarata in \texttt{optstring} viene ritornato un \texttt{?}
138 mentre se l'opzione non è seguita da un parametro viene ritornato un
139 \texttt{:} infine se viene incontrato il valore \texttt{--} la scansione viene
140 considerata conclusa.
141
142 Quando la funzione trova un'opzione essa ritorna il valore numerico del
143 carattere, in questo modo si possono prendere le azioni relative usando un
144 case; la funzione inizializza inoltre alcune varibili globali:
145 \begin{itemize}
146 \item \texttt{char * optarg} contiene il puntatore alla stringa argomento
147   dell'opzione.
148 \item \texttt{int optind} alla fine della scansione restituisce l'indice del
149   primo argomento che non è un'opzione.
150 \item \texttt{int opterr} previene, se posto a zero, la stampa di un messaggio
151   di errore in caso di riconoscimento di opzioni non definite.
152 \item \texttt{int optopt} contiene il carattere dell'opzione non riconosciuta.
153 \end{itemize}
154
155 In \nfig è mostrato un programma di esempio, 
156
157
158 \begin{figure}[htbp]
159   \footnotesize
160     \begin{lstlisting}{}
161     opterr = 0;  /* don't want writing to stderr */
162     while ( (i = getopt(argc, argv, "o:a:i:hve")) != -1) {
163         switch (i) {
164         case 'i':   /* input file */
165             in_file=open(optarg,O_RDONLY);
166             if (in_file<0) {
167                 perror("Cannot open input file");
168                 exit(1);
169             }
170             break;
171         case 'o':   /* output file (overwrite) */
172             out_file=open(optarg,O_WRONLY|O_CREAT);
173             if (out_file<0) {
174                 perror("Cannot open output file");
175                 exit(1);
176             }
177             break;
178             break;
179         case 'a':   /* output file (append) */
180             out_file=open(optarg,O_WRONLY|O_CREAT|O_APPEND);
181             break;
182         case 'h':   /* print help usage */
183             usage();
184             break;
185         case 'v':   /* set verbose mode */
186             debug("Option -v active\n");
187             verbose=1;
188             break;
189         case '?':   /* unrecognized options */
190             printf("Unrecognized options -%c\n",optopt);
191             usage();
192         default:    /* should not reached */
193             debug("default option\n");
194             usage();
195         }
196     }
197     debug("Optind %d, argc %d\n",optind,argc);
198   \end{lstlisting}
199   \caption{Esempio di codice per la gestione delle opzioni.}
200   \label{fig:proc_options_code}
201 \end{figure}
202
203 \subsection{Opzioni in formato esteso}
204 \label{sec:proc_opt_extended}
205
206 Un'estensione di questo schema è costituito dalle cosiddette
207 \textit{long-options} espresse nella forma \texttt{--option=parameter}, anche
208 la gestione di queste ultime è stata standardizzata attraverso l'uso di una
209 versione estesa di \texttt{getopt}.
210
211
212 \subsection{Le variabili di ambiente}
213 \label{sec:proc_env_var}
214
215 Questo va fatto.
216
217
218
219 \section{La gestione della memoria}
220 \label{sec:proc_memory_manag}