1 \chapter{La gestione avanzata dei file}
2 \label{cha:file_advanced}
4 In questo capitolo affronteremo le tematiche relative alla gestione avanzata
5 dei file, che non sono state trattate in \capref{cha:file_unix_interface},
6 dove ci si è limitati ad una panoramica delle funzioni base. In particolare
7 tratteremo delle funzioni di input/output avanzato e del \textit{file
11 \section{Le funzioni di I/O avanzato}
12 \label{sec:file_advanced_io}
14 In questa sezione esamineremo le funzioni che permettono una gestione più
15 sofisticata dell'I/O su file, a partire da quelle che permettono di gestire
16 l'accesso contemporaneo a più file, per concludere con la gestione dell'I/O
20 \subsection{La modalità di I/O \textsl{non-bloccante}}
21 \label{sec:file_noblocking}
23 Abbiamo visto in \secref{sec:sig_gen_beha}, affrontando la suddivisione fra
24 \textit{fast} e \textit{slow} system call, che in certi casi le funzioni di
25 I/O possono bloccarsi indefinitamente.\footnote{si ricordi però che questo può
26 accadere solo per le pipe, i socket ed alcuni file di dispositivo; sui file
27 normali le funzioni di lettura e scrittura ritornano sempre subito.} Ad
28 esempio le operazioni di lettura possono bloccarsi quando non ci sono dati
29 disponibili sul descrittore su cui si sta operando.
31 Questo comportamento causa uno dei problemi più comuni che ci si trova ad
32 affrontare nelle operazioni di I/O, che è quello che si verifica quando si
33 devono eseguire operazioni che possono bloccarsi su più file descriptor:
34 mentre si è bloccati su uno di essi su di un'altro potrebbero essere presenti
35 dei dati; così che nel migliore dei casi si avrebbe una lettura ritardata
36 inutilmente, e nel peggiore si potrebbe addirittura arrivare ad un deadlock.
38 Abbiamo già accennato in \secref{sec:file_open} che è possibile prevenire
39 questo tipo di comportamento aprendo un file in modalità
40 \textsl{non-bloccante}, attraverso l'uso del flag \macro{O\_NONBLOCK} nella
41 chiamata di \func{open}. In questo caso le funzioni di input/output che
42 altrimenti si sarebbero bloccate ritornano immediatamente, restituendo
43 l'errore \macro{EAGAIN}.
45 L'utilizzo di questa modalità di I/O permette di risolvere il problema
46 controllando a turno i vari file descriptor, in un ciclo in cui si ripete
47 l'accesso fintanto che esso non viene garantito. Ovviamente questa tecnica,
48 detta \textit{polling}, è estremamente inefficiente: si tiene costantemente
49 impiegata la CPU solo per eseguire in continuazione delle system call che
50 nella gran parte dei casi falliranno. Per evitare questo, come vedremo in
51 \secref{sec:file_multiplexing}, è stata introdotta una nuova interfaccia di
52 programmazione, che comporta comunque l'uso della modalità di I/O non
57 \subsection{L'I/O multiplexing}
58 \label{sec:file_multiplexing}
60 Per superare il problema di dover usare il \textit{polling} per controllare la
61 possibilità di effettuare operazioni su un file aperto in modalità non
62 bloccante, sia BSD che System V hanno introdotto delle nuove funzioni in grado
63 di sospendere l'esecuzione di un processo in attesa che l'accesso diventi
64 possibile. Il primo ad introdurre questa modalità di operazione, chiamata
65 usualmente \textit{I/O multiplexing}, è stato BSD,\footnote{la funzione è
66 apparsa in BSD4.2 e standardizzata in BSD4.4, ma è stata portata su tutti i
67 sistemi che supportano i \textit{socket}, compreso le varianti di System V.}
68 con la funzione \func{select}, il cui prototipo è:
71 \headdecl{sys/types.h}
73 \funcdecl{int select(int n, fd\_set *readfds, fd\_set *writefds, fd\_set
74 *exceptfds, struct timeval *timeout)}
76 Attende che uno dei file descriptor degli insiemi specificati diventi
79 \bodydesc{La funzione in caso di successo restituisce il numero di file
80 descriptor (anche nullo) che sono attivi, e -1 in caso di errore, nel qual
81 caso \var{errno} viene impostata ai valori:
83 \item[\macro{EBADF}] Si è specificato un file descriptor sbagliato in uno
85 \item[\macro{EINTR}] La funzione è stata interrotta da un segnale.
86 \item[\macro{EINVAL}] Si è specificato per \param{n} un valore negativo.
88 ed inoltre \macro{ENOMEM}.
92 La funzione mette il processo in stato di \textit{sleep} (vedi
93 \tabref{tab:proc_proc_states}) fintanto che almeno uno dei file descriptor
94 degli insiemi specificati (\param{readfds}, \param{writefds} e
95 \param{exceptfds}), non diventa attivo, per un tempo massimo specificato da
98 Per specificare quali file descriptor si intende \textsl{selezionare}, la
99 funzione usa un particolare oggetto, il \textit{file descriptor set},
100 identificato dal tipo \type{fd\_set}, che serve ad identificare un insieme di
101 file descriptor, (in maniera analoga a come un \textit{signal set}, vedi
102 \secref{sec:sig_sigset}, identifica un insieme di segnali). Per la
103 manipolazione di questi \textit{file descriptor set} si possono usare delle
104 opportune macro di preprocessore:
106 \headdecl{sys/time.h}
107 \headdecl{sys/types.h}
109 \funcdecl{FD\_ZERO(fd\_set *set)}
110 Inizializza l'insieme (vuoto).
112 \funcdecl{FD\_SET(int fd, fd\_set *set)}
113 Inserisce il file descriptor \param{fd} nell'insieme.
115 \funcdecl{FD\_CLR(int fd, fd\_set *set)}
116 Rimuove il file descriptor \param{fd} nell'insieme.
118 \funcdecl{FD\_ISSET(int fd, fd\_set *set)}
119 Controlla se il file descriptor \param{fd} è nell'insieme.
122 In genere un \textit{file descriptor set} può contenere fino ad un massimo di
123 \macro{FD\_SETSIZE} file descriptor. Questo valore in origine corrispondeva
124 al limite per il numero massimo di file aperti\footnote{ad esempio in Linux,
125 fino alla serie 2.0.x, c'era un limite di 256 file per processo.}, ma
126 quando, come nelle versioni più recenti del kernel, non c'è più un limite
127 massimo, esso indica le dimensioni massime dei numeri usati nei \textit{file
130 La funzione richiede di specificare tre insiemi distinti di file descriptor;
131 il primo, \param{readfds}, verrà osservato per rilevare la disponibilità di
132 effettuare una lettura, il secondo, \param{writefds}, per verificare la
133 possibilità effettuare una scrittura ed il terzo, \param{exceptfds}, per
134 verificare l'esistenza di condizioni eccezionali (come i messaggi urgenti su
135 un \textit{socket}\index{socket}, vedi \secref{sec:xxx_urgent}).
137 La funzione inoltre richiede anche di specificare, tramite l'argomento
138 \param{n}, un valore massimo del numero dei file descriptor usati
139 nell'insieme; si può usare il già citato \macro{FD\_SETSIZE}, oppure il numero
140 più alto dei file descriptor usati nei tre insiemi, aumentato di uno.
142 Infine l'argomento \param{timeout}, specifica un tempo massimo di
143 attesa\footnote{il tempo è valutato come \textit{elapsed time}.} prima che la
144 funzione ritorni; se impostato a \macro{NULL} la funzione attende
145 indefinitamente. Si può specificare anche un tempo nullo (cioè una \var{struct
146 timeval} con i campi impostati a zero), qualora si voglia semplicemente
147 controllare lo stato corrente dei file descriptor.
149 La funzione restituisce il totale dei file descriptor pronti nei tre insiemi,
150 il valore zero indica sempre che si è raggiunto un timeout. Ciascuno dei tre
151 insiemi viene sovrascritto per indicare quale file descriptor è pronto per le
152 operazioni ad esso relative, in modo da poterlo controllare con la macro
153 \macro{FD\_ISSET}. In caso di errore la funzione restituisce -1 e gli insiemi
156 In Linux \func{select} modifica anche il valore di \param{timeout},
157 impostandolo al tempo restante; questo è utile quando la funzione viene
158 interrotta da un segnale, in tal caso infatti si ha un errore di
159 \macro{EINTR}, ed occorre rilanciare la funzione; in questo modo non è
160 necessario ricalcolare tutte le volte il tempo rimanente.\footnote{questo può
161 causare problemi di portabilità sia quando si trasporta codice scritto su
162 Linux che legge questo valore, sia quando si usano programmi scritti per
163 altri sistemi che non dispongono di questa caratteristica e ricalcolano
164 \param{timeout} tutte le volte. In genere la caratteristica è disponibile
165 nei sistemi che derivano da System V e non disponibile per quelli che
168 Come accennato l'interfaccia di \func{select} è una estensione di BSD; anche
169 System V ha introdotto una sua interfaccia per gestire l'\textit{I/O
170 multiplexing}, basata sulla funzione \func{poll},\footnote{la funzione è
171 prevista dallo standard XPG4, ed è stata introdotta in Linux come system
172 call a partire dal kernel 2.1.23 e dalle \acr{libc} 5.4.28.} il cui prototipo è:
173 \begin{prototype}{sys/poll.h}
174 {int poll(struct pollfd *ufds, unsigned int nfds, int timeout)}
176 La funzione attente un cambiamento di stato per uno dei file descriptor
177 specificati da \param{ufds}.
179 \bodydesc{La funzione restituisce il numero di file descriptor con attività in
180 caso di successo, o 0 se c'è stato un timeout; in caso di errore viene
181 restituito -1 ed \var{errno} viene impostata ai valori:
183 \item[\macro{EBADF}] Si è specificato un file descriptor sbagliato in uno
185 \item[\macro{EINTR}] La funzione è stata interrotta da un segnale.
187 ed inoltre \macro{EFAULT} e \macro{ENOMEM}.}
190 La funzione tiene sotto controllo un numero \param{ndfs} di file descriptor
191 specificati attraverso un vettore di puntatori a strutture di tipo
192 \type{pollfd}, la cui definizione è riportata in \figref{fig:file_pollfd}.
193 Come \func{select} anche \func{poll} permette di interrompere l'attesa dopo un
194 certo tempo, che va specificato attraverso \param{timeout} in numero di
195 millisecondi (un valore negativo indica un'attesa indefinita).
198 \footnotesize \centering
199 \begin{minipage}[c]{15cm}
200 \begin{lstlisting}[labelstep=0]{}%,frame=,indent=1cm]{}
202 int fd; /* file descriptor */
203 short events; /* requested events */
204 short revents; /* returned events */
209 \caption{La struttura \type{pollfd}, utilizzata per specificare le modalità
210 di controllo di un file descriptor alla funzione \func{poll}.}
211 \label{fig:file_pollfd}
214 Per ciascun file da controllare deve essere opportunamente predisposta una
215 struttura \type{pollfd}; nel campo \var{fd} deve essere specificato il file
216 descriptor, mentre nel campo \var{events} il tipo di evento su cui si vuole
217 attendere; quest'ultimo deve essere specificato come maschera binaria dei
218 primi tre valori riportati in \tabref{tab:file_pollfd_flags} (gli altri
219 vengono utilizzati solo per \var{revents} come valori in uscita).
224 \begin{tabular}[c]{|l|c|l|}
226 \textbf{Flag} & \textbf{Valore} & \textbf{Significato} \\
229 \macro{POLLIN} & 0x001 & È possibile la lettura immediata.\\
230 \macro{POLLPRI} & 0x002 & Sono presenti dati urgenti.\\
231 \macro{POLLOUT} & 0x004 & È possibile la scrittura immediata.\\
233 \macro{POLLERR} & 0x008 & C'è una condizione di errore.\\
234 \macro{POLLHUP} & 0x010 & Si è verificato un hung-up.\\
235 \macro{POLLNVAL} & 0x020 & Il file descriptor non è aperto.\\
237 \macro{POLLRDNORM}& 0x040 & Sono disponibili in lettura dati normali.\\
238 \macro{POLLRDBAND}& 0x080 & Sono disponibili in lettura dati ad alta
240 \macro{POLLWRNORM}& 0x100 & È possibile la scrittura di dati normali. \\
241 \macro{POLLWRBAND}& 0x200 & È possibile la scrittura di dati ad
243 \macro{POLLMSG} & 0x400 & Estensione propria di Linux.\\
246 \caption{Costanti per l'identificazione dei vari bit dei campi
247 \var{events} e \var{revents} di \type{pollfd}.}
248 \label{tab:file_pollfd_flags}
251 La funzione ritorna, restituendo il numero di file per i quali si è verificata
252 una delle condizioni di attesa richieste od un errore. Lo stato dei file
253 all'uscita della funzione viene restituito nel campo \var{revents} della
254 relativa struttura \type{pollfd}, che viene impostato alla maschera binaria
255 dei valori riportati in \tabref{tab:file_pollfd_flags}, ed oltre alle tre
256 condizioni specificate tramite \var{events} può riportare anche l'occorrere di
257 una condizione di errore.
259 Lo standard POSIX è rimasto a lungo senza primitive per l'\textit{I/O
260 multiplexing}, che è stata introdotto con le ultime revisioni dello standard
261 (POSIX 1003.1g-2000 e POSIX 1003.1-2001). Esso prevede che tutte le funzioni
262 ad esso relative vengano dichiarate nell'header \file{sys/select.h}, che
263 sostituisce i precedenti, ed aggiunge a \func{select} una nuova funzione
264 \func{pselect},\footnote{il supporto per lo standard POSIX 1003.1-2001, ed
265 l'header \file{sys/select.h}, compaiono in Linux a partire dalle \acr{glibc}
266 2.1. Le \acr{libc4} e \acr{libc5} non contengono questo header, le
267 \acr{glibc} 2.0 contengono una definizione sbagliata di \func{psignal},
268 senza l'argomento \param{sigmask}, la definizione corretta è presente dalle
269 \acr{glibc} 2.1-2.2.1 se si è definito \macro{\_GNU\_SOURCE} e nelle
270 \acr{glibc} 2.2.2-2.2.4 se si è definito \macro{\_XOPEN\_SOURCE} con valore
271 maggiore di 600.} il cui prototipo è:
272 \begin{prototype}{sys/select.h}
273 {int pselect(int n, fd\_set *readfds, fd\_set *writefds, fd\_set *exceptfds,
274 struct timespec *timeout, sigset\_t *sigmask)}
276 Attende che uno dei file descriptor degli insiemi specificati diventi
279 \bodydesc{La funzione in caso di successo restituisce il numero di file
280 descriptor (anche nullo) che sono attivi, e -1 in caso di errore, nel qual
281 caso \var{errno} viene impostata ai valori:
283 \item[\macro{EBADF}] Si è specificato un file descriptor sbagliato in uno
285 \item[\macro{EINTR}] La funzione è stata interrotta da un segnale.
286 \item[\macro{EINVAL}] Si è specificato per \param{n} un valore negativo.
288 ed inoltre \macro{ENOMEM}.}
291 La funzione è sostanzialmente identica a \func{select}, solo che usa una
292 struttura \type{timespec} per indicare con maggiore precisione il timeout e
293 non ne aggiorna il valore in caso di interruzione, inoltre prende un argomento
294 aggiuntivo \param{sigmask} che è il puntatore ad una maschera di segnali (si
295 veda \secref{sec:sig_sigmask}). La maschera corrente viene sostituita da
296 questa immediatamente prima di eseguire l'attesa, e ripristinata al ritorno
299 L'uso di \param{sigmask} è stato introdotto allo scopo di prevenire possibili
300 race condition\footnote{in Linux però, non esistendo una system call apposita,
301 la funzione è implementata nelle \acr{glibc} usando \func{select}, e la
302 possibilità di una race condition resta.} quando si deve eseguire un test su
303 una variabile assegnata da un manipolatore sulla base dell'occorrenza di un
304 segnale per decidere se lanciare \func{select}. Fra il test e l'esecuzione è
305 presente una finestra in cui potrebbe arrivare il segnale che non sarebbe
306 rilevato; la race condition diventa superabile disabilitando il segnale prima
307 del test e riabilitandolo poi grazie all'uso di \param{sigmask}.
311 \subsection{L'\textsl{I/O asincrono}}
312 \label{sec:file_asyncronous_io}
314 Una modalità alternativa all'uso dell'\textit{I/O multiplexing} è quella di
315 fare ricorso al cosiddetto \textsl{I/O asincrono}. Il concetto base
316 dell'\textsl{I/O asincrono} è che le funzioni di I/O non attendono il
317 completamento delle operazioni prima di ritornare, così che il processo non
318 viene bloccato. In questo modo diventa ad esempio possibile effettuare una
319 richiesta preventiva di dati, in modo da poter effettuare in contemporanea le
320 operazioni di calcolo e quelle di I/O.
322 Abbiamo accennato in \secref{sec:file_open} che è possibile, attraverso l'uso
323 del flag \macro{O\_ASYNC},\footnote{l'uso del flag di \macro{O\_ASYNC} e dei
324 comandi \macro{F\_SETOWN} e \macro{F\_GETOWN} per \func{fcntl} è specifico
325 di Linux e BSD.} aprire un file in modalità asincrona, così come è possibile
326 attivare in un secondo tempo questa modalità impostando questo flag attraverso
327 l'uso di \func{fcntl} con il comando \macro{F\_SETFL} (vedi
328 \secref{sec:file_fcntl}).
330 In realtà in questo caso non si tratta di I/O asincrono vero e proprio, quanto
331 di un meccanismo asincrono di notifica delle variazione dello stato del file
332 descriptor; quello che succede è che il sistema genera un segnale (normalmente
333 \macro{SIGIO}, ma è possibile usarne altri) tutte le volte che diventa
334 possibile leggere o scrivere dal file descriptor che si è posto in questa
335 modalità. Si può inoltre selezionare, con il comando \macro{F\_SETOWN} di
336 \func{fcntl}, quale processo (o gruppo di processi) riceverà il segnale.
338 In questo modo si può evitare l'uso delle funzioni \func{poll} o \func{select}
339 che, quando vengono usate con un numero molto grande di file descriptor, non
340 hanno buone prestazioni. In tal caso infatti la maggior parte del loro tempo
341 di esecuzione è impegnato ad eseguire una scansione su tutti i file descriptor
342 tenuti sotto controllo per determinare quali di essi (in genere una piccola
343 percentuale) sono diventati attivi.
345 Tuttavia con l'implementazione classica dei segnali questa modalità di I/O
346 presenta notevoli problemi, dato che non è possibile determinare, quando sono
347 più di uno, qual'è il file descriptor responsabile dell'emissione del segnale.
348 Linux però supporta le estensioni POSIX.1b dei segnali che permettono di
349 superare il problema facendo ricorso alle informazioni aggiuntive restituite
350 attraverso la struttura \type{siginfo\_t}, utilizzando la forma estesa
351 \var{sa\_sigaction} del manipolatore (si riveda quanto illustrato in
352 \secref{sec:sig_sigaction}).
354 Per far questo però occorre utilizzare le funzionalità dei segnali real-time
355 (vedi \secref{sec:sig_real_time}) imopstando esplicitamente con il comando
356 \macro{F\_SETSIG} di \func{fcntl} un segnale real-time da inviare in caso di
357 I/O asincrono (il segnale predefinito è \macro{SIGIO}). In questo caso il
358 manipolatore tutte le volte che riceverà \macro{SI\_SIGIO} come valore del
359 campo \var{si\_code}\footnote{il valore resta \macro{SI\_SIGIO} qualunque sia
360 il segnale che si è associato all'I/O asincrono, ed indica appunto che il
361 segnale è stato generato a causa di attività nell'I/O asincrono.} di
362 \type{siginfo\_t}, troverà nel campo \var{si\_fd} il valore del file
363 descriptor che ha generato il segnale.
365 Un secondo vantaggio dell'uso dei segnali real-time è che essendo dotati di
366 una coda di consegna ogni segnale sarà associato ad uno solo file descriptor;
367 inoltre sarà possibile stabilire delle priorità nella risposta a seconda del
368 segnale usato. In questo modo si può identificare immediatamente un file su
369 cui l'accesso è diventato possibile evitando completamente l'uso di funzioni
370 come \func{poll} e \func{select}, almeno fintanto che non si satura la coda;
371 si eccedono le dimensioni di quest'ultima; in tal caso infatti il kernel, non
372 potendo più assicurare il comportamento corretto per un segnale real-time,
373 invierà al suo posto un \var{SIGIO}, su cui si accumuleranno tutti i segnali
374 in eccesso, e si dovrà determinare al solito modo quali sono i file diventati
377 Benché la modalità di apertura asincrona di un file possa risultare utile in
378 varie occasioni (in particolar modo con i socket e gli altri file per i quali
379 le funzioni di I/O sono system call lente), essa è comunque limitata alla
380 notifica della disponibilità del file descriptor per le operazioni di I/O, e
381 non ad uno svolgimento asincrono delle medesime. Lo standard POSIX.1b
382 definisce anche una interfaccia apposita per l'I/O asincrono, che prevede un
383 insieme di funzioni dedicate, completamente separate rispetto a quelle usate
386 In generale questa interfaccia è completamente astratta e può essere
387 implementata sia direttamente nel kernel, che in user space attraverso l'uso
388 di thread. Al momento\footnote{fino ai kernel della serie 2.4.x, nella serie
389 2.5.x è però iniziato un lavoro completo di riscrittura di tutto il sistema
390 di I/O, che prevede anche l'introduzione di un nuovo layer per l'I/O
391 asincrono.} esiste una sola versione stabile di questa interfaccia, quella
392 delle \acr{glibc}, che è realizzata completamente in user space. Esistono
393 comunque vari progetti sperimentali (come il KAIO della SGI, o i patch di
394 Benjamin La Haise) che prevedono un supporto diretto da parte del kernel.
396 Lo standard prevede che tutte le operazioni di I/O asincrono siano controllate
397 attraverso l'uso di una apposita struttura \type{aiocb} (il cui nome sta per
398 \textit{asyncronous I/O control block}), che viene passata come argomento a
399 tutte le funzioni dell'interfaccia. La sua definizione, come effettuata in
400 \file{aio.h}, è riportata in \figref{fig:file_aiocb}. Nello steso file è
401 definita la macro \macro{\_POSIX\_ASYNCHRONOUS\_IO}, che dichiara la
402 disponibilità dell'interfaccia per l'I/O asincrono.
405 \footnotesize \centering
406 \begin{minipage}[c]{15cm}
407 \begin{lstlisting}[labelstep=0]{}%,frame=,indent=1cm]{}
410 int aio_fildes; /* File descriptor. */
411 off_t aio_offset; /* File offset */
412 int aio_lio_opcode; /* Operation to be performed. */
413 int aio_reqprio; /* Request priority offset. */
414 volatile void *aio_buf; /* Location of buffer. */
415 size_t aio_nbytes; /* Length of transfer. */
416 struct sigevent aio_sigevent; /* Signal number and value. */
421 \caption{La struttura \type{aiocb}, usata per il controllo dell'I/O
423 \label{fig:file_aiocb}
426 Le operazioni di I/O asincrono possono essere effettuate solo su un file già
427 aperto; il file deve inoltre supportare la funzione \func{lseek},
428 pertanto terminali e pipe sono esclusi. Non c'è limite al numero di operazioni
429 contemporanee effettuabili su un singolo file.
431 Ogni operazione deve inizializzare opportunamente un \textit{control block}.
432 Il file descriptor su cui operare deve essere specificato tramite il campo
433 \var{aio\_fildes}; dato che più operazioni possono essere eseguita in maniera
434 asincrona, il concetto di posizione corrente sul file viene a mancare;
435 pertanto si deve sempre specificare nel campo \var{aio\_offset} la posizione
436 sul file da cui i dati saranno letti o scritti. Nel campo \var{aio\_buf} deve
437 essere specificato l'indirizzo del buffer usato per l'I/O, ed in
438 \var{aio\_nbytes} la lunghezza del blocco di dati da trasferire.
440 Il campo \var{aio\_reqprio} permette di impostare la priorità delle operazioni
441 di I/O.\footnote{in generale perché ciò sia possibile occorre che la
442 piattaforma supporti questa caratteristica, questo viene indicato definendo
443 le macro \macro{\_POSIX\_PRIORITIZED\_IO}, e
444 \macro{\_POSIX\_PRIORITY\_SCHEDULING}.} La priorità viene impostata a
445 partire da quella del processo chiamante (vedi \secref{sec:proc_priority}),
446 cui viene sottratto il valore di questo campo.
448 Il campo \var{aio\_lio\_opcode} è usato soltanto dalla funzione
449 \func{lio\_listio}, che, come vedremo più avanti, permette di eseguire con una
450 sola chiamata una serie di operazioni, usando un vettore di \textit{control
451 block}. Tramite questo campo si specifica quale è la natura di ciascuna di
455 \footnotesize \centering
456 \begin{minipage}[c]{15cm}
457 \begin{lstlisting}[labelstep=0]{}%,frame=,indent=1cm]{}
460 sigval_t sigev_value;
463 sigev_notify_function;
464 sigev_notify_attributes;
469 \caption{La struttura \type{sigevent}, usata per specificare le modalità di
470 notifica degli eventi relativi alle operazioni di I/O asincrono.}
471 \label{fig:file_sigevent}
474 Infine il campo \var{aio\_sigevent} è una struttura di tipo \type{sigevent}
475 che serve a specificare il modo in cui si vuole che venga effettuata la
476 notifica del completamento delle operazioni richieste. La struttura è
477 riportata in \secref{fig:file_sigevent}; il campo \var{sigev\_notify} è quello
478 che indica le modalità della notifica, esso può assumere i tre valori:
479 \begin{basedescript}{\desclabelwidth{3.0cm}}
480 \item[\macro{SIGEV\_NONE}] Non viene inviata nessuna notifica.
481 \item[\macro{SIGEV\_SIGNAL}] La notifica viene effettuata inviando al processo
482 chiamante il segnale specificato nel campo \var{sigev\_signo}, se il
483 manipolatore è installato con \macro{SA\_SIGINFO}, il gli verrà restituito
484 il valore di \var{sigev\_value} in come valore del campo \var{si\_value} per
486 \item[\macro{SIGEV\_THREAD}] La notifica viene effettuata creando un nuovo
487 thread che esegue la funzione specificata da \var{sigev\_notify\_function},
488 con gli attributi specificati da \var{sigev\_notify\_attribute}.
491 Le due funzioni base dell'interfaccia per l'I/O asincrono sono
492 \func{aio\_read} ed \func{aio\_write}. Esse permettono di richiedere una
493 lettura od una scrittura asincrona di dati, usando la struttura \type{aiocb}
494 appena descritta; i rispettivi prototipi sono:
498 \funcdecl{int aio\_read(struct aiocb *aiocbp)}
499 Richiede una lettura asincrona secondo quanto specificato con \param{aiocbp}.
501 \funcdecl{int aio\_write(struct aiocb *aiocbp)}
502 Richiede una scrittura asincrona secondo quanto specificato con
505 \bodydesc{Le funzioni restituiscono 0 in caso di successo, e -1 in caso di
506 errore, nel qual caso \var{errno} viene impostata ai valori:
508 \item[\macro{EBADF}] Si è specificato un file descriptor sbagliato.
509 \item[\macro{ENOSYS}] La funzione non è implementata.
510 \item[\macro{EINVAL}] Si è specificato un valore non valido per i campi
511 \var{aio\_offset} o \var{aio\_reqprio} di \param{aiocbp}.
512 \item[\macro{EAGAIN}] La coda delle richieste è momentaneamente piena.
517 Entrambe le funzioni ritornano immediatamente dopo aver messo in coda la
518 richiesta, o in caso di errore. Non è detto che gli errori \macro{EBADF} ed
519 \macro{EINVAL} siano rilevati immediatamente al momento della chiamata,
520 potrebbero anche emergere nelle fasi successive delle operazioni. Lettura e
521 scrittura avvengono alla posizione indicata da \var{aio\_offset}, a meno che
522 il file non sia stato aperto in \textit{append mode} (vedi
523 \secref{sec:file_open}), nel qual caso le scritture vengono effettuate
524 comunque alla fine de file, nell'ordine delle chiamate a \func{aio\_write}.
526 Si tenga inoltre presente che deallocare la memoria indirizzata da
527 \param{aiocbp} o modificarne i valori prima della conclusione di una
528 operazione può dar luogo a risultati impredicibili, perché l'accesso ai vari
529 campi per eseguire l'operazione può avvenire in un momento qualsiasi dopo la
530 richiesta. Questo comporta che occorre evitare di usare per \param{aiocbp}
531 variabili automatiche e che non si deve riutilizzare la stessa struttura per
532 un ulteriore operazione fintanto che la precedente non sia stata ultimata. In
533 generale per ogni operazione di I/O asincrono si deve utilizzare una diversa
534 struttura \type{aiocb}.
536 Dato che si opera in modalità asincrona, il successo di \func{aio\_read} o
537 \func{aio\_write} non implica che le operazioni siano state effettivamente
538 eseguite in maniera corretta; per verificarne l'esito l'interfaccia prevede
539 altre due funzioni, che permettono di controllare lo stato di esecuzione. La
540 prima è \func{aio\_error}, che serve a determinare un eventuale stato di
541 errore; il suo prototipo è:
542 \begin{prototype}{aio.h}
543 {int aio\_error(const struct aiocb *aiocbp)}
545 Determina lo stato di errore delle operazioni di I/O associate a
548 \bodydesc{La funzione restituisce 0 se le operazioni si sono concluse con
549 successo, altrimenti restituisce il codice di errore.}
550 % }, che viene salvato
551 % anche in \var{errno}, i valori possibili sono:
553 % \item[\macro{ENOSYS}] La funzione non è implementata.
554 % \item[\macro{EINPROGRESS}] L'operazione è ancora in corso.
555 % \item[\macro{EINVAL}] Si è specificato un valore non valido per i campi
556 % \var{aio\_offset} o \var{aio\_reqprio} di \param{aiocbp}.
557 % \item[\macro{EBADF}] Si è specificato un file descriptor sbagliato.
559 % più tutti quelli possibili per le sottostanti operazioni, .}
562 Se l'operazione non si è ancora completata viene restituito l'errore di
563 \macro{EINPROGRESS}. La funzione ritorna zero quando l'operazione si è
564 conclusa con successo, altrimenti restituisce il codice dell'errore
565 verificatosi, ed esegue la corrispondente impostazione di \var{errno}. Il
566 codice può essere sia \macro{EINVAL} ed \macro{EBADF}, dovuti ad un valore
567 errato per \param{aiocbp}, che uno degli errori possibili durante l'esecuzione
568 dell'operazione di I/O richiesta, nel qual caso saranno restituiti, a seconda
569 del caso, i codici di errore delle system call \func{read}, \func{write} e
572 Una volta che si sia certi che le operazioni siano state concluse (cioè dopo
573 che una chiamata ad \func{aio\_error} non ha restituito \macro{EINPROGRESS},
574 si potrà usare la seconda funzione dell'interfaccia, \func{aio\_return}, che
575 permette di verificare il completamento delle operazioni di I/O asincrono; il
577 \begin{prototype}{aio.h}
578 {ssize\_t aio\_return(const struct aiocb *aiocbp)}
580 Recupera il valore dello stato di ritorno delle operazioni di I/O associate a
583 \bodydesc{La funzione restituisce lo stato di uscita dell'operazione
587 La funzione deve essere chiamata una sola volte per ciascuna operazione
588 asincrona, essa infatti fa sì che il sistema rilasci le risorse ad essa
589 associate. É per questo motivo che occorre chiamare la funzione solo dopo che
590 l'operazione cui \param{aiocbp} fa riferimento si è completata. Una chiamata
591 precedente il completamento delle operazioni darebbe risultati indeterminati.
593 La funzione restituisce il valore di ritorno relativo all'operazione eseguita,
594 così come ricavato dalla sottostante system call (il numero di byte letti,
595 scritti o il valore di ritorno di \func{fsync}). É importante chiamare sempre
596 questa funzione, altrimenti le risorse disponibili per le operazioni di I/O
597 asincrono non verrebbero liberate, rischiando di arrivare ad un loro
600 Oltre alle operazioni di lettura e scrittura l'interfaccia POSIX.1b mette a
601 disposizione un'altra operazione, quella di sincronizzazione dell'I/O, essa è
602 compiuta dalla funzione \func{aio\_fsync}, che ha lo stesso effetto della
603 analoga \func{fsync}, ma viene eseguita in maniera asincrona; il suo prototipo
605 \begin{prototype}{aio.h}
606 {ssize\_t aio\_return(int op, struct aiocb *aiocbp)}
608 Richiede la sincronizzazione dei dati per il file indicato da \param{aiocbp}.
610 \bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di
611 errore, che può essere, con le stesse modalità di \func{aio\_read},
612 \macro{EAGAIN}, \macro{EBADF} o \macro{EINVAL}.}
615 La funzione richiede la sincronizzazione delle operazioni di I/O, ritornando
616 immediatamente. L'esecuzione effettiva della sincronizzazione dovrà essere
617 verificata con \func{aio\_error} e \func{aio\_return} come per le operazioni
618 di lettura e scrittura. L'argomento \param{op} permette di indicare la
619 modalità di esecuzione, se si specifica il valore \macro{O\_DSYNC} le
620 operazioni saranno completate con una chiamata a \func{fdatasync}, se si
621 specifica \macro{O\_SYNC} con una chiamata a \func{fsync} (per i dettagli vedi
622 \secref{sec:file_sync}).
624 Il successo della chiamata assicura la sincronizzazione delle operazioni fino
625 allora richieste, niente è garantito riguardo la sincronizzazione dei dati
626 relativi ad eventuali operazioni richieste successivamente. Se si è
627 specificato un meccanismo di notifica questo sarà innescato una volta che le
628 operazioni di sincronizzazione dei dati saranno completate.
630 In alcuni casi può essere necessario interrompere le operazioni (in genere
631 quando viene richiesta un'uscita immediata dal programma), per questo lo
632 standard POSIX.1b prevede una funzioni apposita, \func{aio\_cancel}, che
633 permette di cancellare una operazione richiesta in precedenza; il suo
635 \begin{prototype}{aio.h}
636 {int aio\_cancel(int fildes, struct aiocb *aiocbp)}
638 Richiede la cancellazione delle operazioni sul file \param{fildes} specificate
641 \bodydesc{La funzione restituisce il risultato dell'operazione con un codice
642 di positivo, e -1 in caso di errore, che avviene qualora si sia specificato
643 un valore non valido di \param{fildes}, imposta \var{errno} al valore
647 La funzione permette di cancellare una operazione specifica sul file
648 \param{fildes}, o tutte le operazioni pendenti, specificando \macro{NULL} come
649 valore di \param{aiocbp}. Quando una operazione viene cancellata una
650 successiva chiamata ad \func{aio\_error} riporterà \macro{ECANCELED} come
651 codice di errore, ed il suo codice di ritorno sarà -1, inoltre il meccanismo
652 di notifica non verrà invocato. Se si specifica una operazione relativa ad un
653 altro file descriptor il risultato è indeterminato.
655 In caso di successo, i possibili valori di ritorno per \func{aio\_cancel} sono
656 tre (anch'essi definiti in \file{aio.h}):
657 \begin{basedescript}{\desclabelwidth{3.0cm}}
658 \item[\macro{AIO\_ALLDONE}] indica che le operazioni di cui si è richiesta la
659 cancellazione sono state già completate,
661 \item[\macro{AIO\_CANCELED}] indica che tutte le operazioni richieste sono
664 \item[\macro{AIO\_NOTCANCELED}] indica che alcune delle operazioni erano in
665 corso e non sono state cancellate.
668 Nel caso si abbia \macro{AIO\_NOTCANCELED} occorrerà chiamare
669 \func{aio\_error} per determinare quali sono le operazioni effettivamente
670 cancellate. Le operazioni che non sono state cancellate proseguiranno il loro
671 corso normale, compreso quanto richiesto riguardo al meccanismo di notifica
672 del loro avvenuto completamento.
674 Benché l'I/O asincrono preveda un meccanismo di notifica, l'interfaccia
675 fornisce anche una apposita funzione, \func{aio\_suspend}, che permette di
676 sospendere l'esecuzione del processo chiamante fino al completamento di una
677 specifica operazione; il suo prototipo è:
678 \begin{prototype}{aio.h}
679 {int aio\_suspend(const struct aiocb * const list[], int nent, const struct
682 Attende, per un massimo di \param{timeout}, il completamento di una delle
683 operazioni specificate da \param{list}.
685 \bodydesc{La funzione restituisce 0 se una (o più) operazioni sono state
686 completate, e -1 in caso di errore nel qual caso \var{errno} viene
689 \item[\macro{EAGAIN}] Nessuna operazione è stata completata entro
691 \item[\macro{ENOSYS}] La funzione non è implementata.
692 \item[\macro{EINTR}] La funzione è stata interrotta da un segnale.
697 La funzione permette di bloccare il processo fintanto che almeno una delle
698 \param{nent} operazioni specificate nella lista \param{list} è completata, per
699 un tempo massimo specificato da \param{timout}, o fintanto che non arrivi un
700 segnale.\footnote{si tenga conto che questo segnale può anche essere quello
701 utilizzato come meccanismo di notifica.} La lista deve essere inizializzata
702 con delle strutture \var{aiocb} relative ad operazioni effettivamente
703 richieste, ma può contenere puntatori nulli, che saranno ignorati. In caso si
704 siano specificati valori non validi l'effetto è indefinito. Un valore
705 \macro{NULL} per \param{timout} comporta l'assenza di timeout.
707 Lo standard POSIX.1b infine ha previsto pure una funzione, \func{lio\_listio},
708 che permette di effettuare la richiesta di una intera lista di operazioni di
709 lettura o scrittura; il suo prototipo è:
710 \begin{prototype}{aio.h}
711 {int lio\_listio(int mode, struct aiocb * const list[], int nent, struct
714 Richiede l'esecuzione delle operazioni di I/O elencata da \param{list},
715 secondo la modalità \param{mode}.
717 \bodydesc{La funzione restituisce 0 in caso di successo, e -1 in caso di
718 errore, nel qual caso \var{errno} viene impostata ai valori:
720 \item[\macro{EAGAIN}] Nessuna operazione è stata completata entro
722 \item[\macro{ENOSYS}] La funzione non è implementata.
723 \item[\macro{EINTR}] La funzione è stata interrotta da un segnale.
728 La funzione esegue la richiesta delle \param{nent} operazioni indicate dalla
729 lista \param{list}; questa deve contenere gli indirizzi di altrettanti
730 \textit{control block}, opportunamente inizializzati; in particolare nel caso
731 dovrà essere specificato il tipo di operazione tramite il campo
732 \var{aio\_lio\_opcode}, che può prendere i tre valori:
733 \begin{basedescript}{\desclabelwidth{2.0cm}}
734 \item[\macro{LIO\_READ}] si richiede una operazione di lettura.
735 \item[\macro{LIO\_WRITE}] si richiede una operazione di scrittura.
736 \item[\macro{LIO\_NOP}] non si effettua nessuna operazione.
738 l'ultimo valore viene usato quando si ha a che fare con un vettore di
739 dimensione fissa, per poter specificare solo alcune operazioni, o quando si è
740 dovuto cancellare delle operazioni e si deve ripetere la richiesta per quelle
743 L'argomento \param{mode} permette di stabilire il comportamento della
744 funzione, se viene specificato il valore \macro{LIO\_WAIT} la funzione si
745 blocca fino al completamento di tutte le operazioni richieste; se invece si
746 specifica \macro{LIO\_NOWAIT} la funzione ritorna immediatamente dopo aver
747 messo in coda tutte le richieste. In questo caso il chiamante può richiedere
748 la notifica del completamento di tutte le richieste, impostando l'argomento
749 \param{sig} in maniera analoga a come si fa per il campo \var{aio\_sigevent}
754 \subsection{I/O vettorizzato}
755 \label{sec:file_multiple_io}
757 Un caso abbastanza comune è quello in cui ci si trova a dover eseguire una
758 serie multipla di operazioni di I/O, come una serie di letture o scritture di
759 vari buffer. Un esempio tipico è quando i dati sono strutturati nei campi di
760 una struttura ed essi devono essere caricati o salvati su un file. Benché
761 l'operazione sia facilmente eseguibile attraverso una serie multipla di
762 chiamate, ci sono casi in cui si vuole poter contare sulla atomicità delle
765 Per questo motivo BSD 4.2\footnote{Le due funzioni sono riprese da BSD4.4 ed
766 integrate anche dallo standard Unix 98; fino alle libc5 Linux usava
767 \type{size\_t} come tipo dell'argomento \param{count}, una scelta logica,
768 che è stata dismessa per restare aderenti allo standard.} ha introdotto due
769 nuove system call, \func{readv} e \func{writev}, che permettono di effettuare
770 con una sola chiamata una lettura o una scrittura su una serie di buffer
771 (quello che viene chiamato \textsl{I/O vettorizzato}. I relativi prototipi
776 \funcdecl{int readv(int fd, const struct iovec *vector, int count)} Esegue
777 una lettura vettorizzata da \param{fd} nei \param{count} buffer specificati
780 \funcdecl{int writev(int fd, const struct iovec *vector, int count)} Esegue
781 una scrittura vettorizzata da \param{fd} nei \param{count} buffer
782 specificati da \param{vector}.
784 \bodydesc{Le funzioni restituiscono il numero di byte letti o scritti in
785 caso di successo, e -1 in caso di errore, nel qual caso \var{errno} viene
788 \item[\macro{EBADF}] si è specificato un file descriptor sbagliato.
789 \item[\macro{EINVAL}] si è specificato un valore non valido per uno degli
790 argomenti (ad esempio \param{count} è maggiore di \macro{MAX\_IOVEC}).
791 \item[\macro{EINTR}] la funzione è stata interrotta da un segnale prima di
792 di avere eseguito una qualunque lettura o scrittura.
793 \item[\macro{EAGAIN}] \param{fd} è stato aperto in modalità non bloccante e
794 non ci sono dati in lettura.
795 \item[\macro{EOPNOTSUPP}] La coda delle richieste è momentaneamente piena.
797 ed inoltre \macro{EISDIR}, \macro{ENOMEM}, \macro{EFAULT} (se non sono stato
798 allocati correttamente i buffer specificati nei campi \func{iov\_base}), più
799 tutti gli ulteriori errori che potrebbero avere le usuali funzioni di
800 lettura e scrittura eseguite su \param{fd}.}
803 Entrambe le funzioni usano una struttura \type{iovec}, definita in
804 \figref{fig:file_iovec}, che definisce dove i dati devono essere letti o
805 scritti. Il primo campo, \var{iov\_base}, contiene l'indirizzo del buffer ed
806 il secondo, \var{iov\_len}, la dimensione dello stesso.
809 \footnotesize \centering
810 \begin{minipage}[c]{15cm}
811 \begin{lstlisting}[labelstep=0]{}%,frame=,indent=1cm]{}
813 __ptr_t iov_base; /* Starting address */
814 size_t iov_len; /* Length in bytes */
819 \caption{La struttura \type{iovec}, usata dalle operazioni di I/O
821 \label{fig:file_iovec}
824 I buffer da utilizzare sono specificati attraverso l'argomento \var{vector} che
825 è un vettore di tale strutture, la cui lunghezza è specificata da \param{count}.
826 Essi verranno letti (o scritti) nell'ordine in cui li si sono specificati.
830 \subsection{File mappati in memoria}
831 \label{sec:file_memory_map}
833 Una modalità alternativa di I/O, che usa una interfaccia completamente diversa
834 rispetto a quella classica vista in \capref{cha:file_unix_interface}, è il
835 cosiddetto \textit{memory-mapped I/O}, che attraverso il meccanismo della
836 \textsl{paginazione}\index{paginazione} usato dalla memoria virtuale (vedi
837 \secref{sec:proc_mem_gen}) permette di \textsl{mappare} il contenuto di un
838 file in una sezione dello spazio di indirizzi del processo.
840 Tutto questo comporta una notevole semplificazione delle operazioni di I/O, in
841 quanto non sarà più necessario utilizzare dei buffer intermedi su cui
842 appoggiare i dati da traferire, ma questi potranno essere acceduti
843 direttamente dalla sezione di memoria; inoltre questa interfaccia
844 è più efficiente delle usuali funzioni di I/O, in quanto permette di caricare
845 in memoria solo le parti del file che sono effettivamente usate ad un dato
848 Infatti, dato che l'accesso è fatto direttamente attraverso la memoria
849 virtuale, la sezione di memoria mappata su cui si opera sarà a sua volta letta
850 o scritta sul file una pagina alla volta e solo per le parti effettivamente
851 usate, il tutto in maniera completamente trasparente al processo; l'acceso
852 alle pagine non ancora caricate avverrà allo stesso modo con cui vengono
853 caricate in memoria le pagine che sono state salvate sullo swap.
855 Infine in situazioni in cui la memoria è scarsa, le pagine che mappano un
856 file vengono salvate automaticamente, così come le pagine dei programmi
857 vengono scritte sulla swap; questo consente di accedere ai file su dimensioni
858 il cui solo limite è quello dello spazio di indirizzi disponibile, e non della
859 memoria su cui possono esserne lette delle porzioni.
861 L'interfaccia prevede varie funzioni per la gestione del \textit{memory
862 mapping}, la prima di queste è \func{mmap}, che esegue la mappatura in
863 memoria un file; il suo prototipo è:
867 \headdecl{sys/mman.h}
869 \funcdecl{void * mmap(void *start, size\_t length, int prot, int flags, int
872 Esegue la mappatura in memoria del file \param{fd}.
874 \bodydesc{La funzione restituisce il puntatore alla zona di memoria mappata
875 in caso di successo, e \macro{MAP\_FAILED} (-1) in caso di errore, nel
876 qual caso \var{errno} viene impostata ai valori:
878 \item[\macro{EBADF}] Il file descriptor non è valido, e non si è usato
879 \macro{MAP\_ANONYMOUS}.
880 \item[\macro{EACCES}] Il file descriptor non si riferisce ad un file
881 regolare, o si è richiesto \macro{MAP\_PRIVATE} ma \param{fd} non è
882 aperto in lettura, o si è richiesto \macro{MAP\_SHARED} e impostato
883 \macro{PROT\_WRITE} ed \param{fd} non è aperto in lettura/scrittura, o
884 si è impostato \macro{PROT\_WRITE} ed \param{fd} è in
885 \textit{append-only}.
886 \item[\macro{EINVAL}] I valori di \param{start}, \param{length} o
887 \param{offset} non sono validi (o troppo grandi o non allineati sulla
888 dimensione delle pagine).
889 \item[\macro{ETXTBSY}] Si è impostato \macro{MAP\_DENYWRITE} ma \param{fd}
890 è aperto in scrittura.
891 \item[\macro{EAGAIN}] Il file è bloccato, o si è bloccata troppa memoria.
892 \item[\macro{ENOMEM}] Non c'è memoria o si è superato il limite sul numero
893 di mappature possibili.
894 \item[\macro{ENODEV}] Il filesystem di \param{fd} no supporta il memory
900 La funzione richiede di mappare in memoria la sezione del file \param{fd} a
901 partire da \param{offset} per \param{lenght} byte, preferibilmente
902 all'indirizzo \param{start}. Il valore di \param{offset} deve essere un
903 multiplo della dimensione di una pagina di memoria. Il valore dell'argomento
904 \param{prot} indica la protezione\footnote{in Linux la memoria reale è divisa
905 in pagine: ogni processo vede la sua memoria attraverso uno o più segmenti
906 lineari di memoria virtuale. Per ciascuno di questi segmenti il kernel
907 mantiene nella \textit{page table} la mappatura sulle pagine di memoria
908 reale, ed le modalità di accesso (lettura, esecuzione, scrittura); una loro
909 violazione causa quella che si chiama una \textit{segment violation}, e la
910 relativa emissione del segnale \macro{SIGSEGV}.} da applicare al segmento di
911 memoria e deve essere specificato come maschera binaria ottenuta dall'OR di
912 uno o più dei valori riportati in \tabref{tab:file_mmap_flag}; il valore
913 specificato deve essere compatibile con la modalità con cui si è aperto il
919 \begin{tabular}[c]{|l|l|}
921 \textbf{Valore} & \textbf{Significato} \\
924 \macro{PROT\_EXEC} & Le pagine possono essere eseguite.\\
925 \macro{PROT\_READ} & Le pagine possono essere lette.\\
926 \macro{PROT\_WRITE} & Le pagine possono essere scritte.\\
927 \macro{PROT\_NONE} & L'accesso alle pagine è vietato.\\
930 \caption{Valori dell'argomento \param{prot} di \func{mmap}, relativi alla
931 protezione applicate alle pagine del file mappate in memoria.}
932 \label{tab:file_mmap_prot}
935 L'argomento \param{flags} specifica qual'è il tipo di oggetto mappato, le
936 opzioni relative alle modalità con cui è effettuata la mappatura e alle
937 modalità con cui le modifiche alla memoria mappata vengono condivise o
938 mantenute private al processo che le ha effettuate. Deve essere specificato
939 come maschera binaria ottenuta dall'OR di uno o più dei valori riportati in
940 \tabref{tab:file_mmap_flag}.
945 \begin{tabular}[c]{|l|p{10cm}|}
947 \textbf{Valore} & \textbf{Significato} \\
950 \macro{MAP\_FIXED} & Non permette di restituire un indirizzo diverso
951 da \param{start}, se questo non può essere usato
952 \func{mmap} fallisce. Se si imposta questo flag il
953 valore di \param{start} deve essere allineato
954 alle dimensioni di una pagina. \\
955 \macro{MAP\_SHARED} & I cambiamenti sulla memoria mappata vengono
956 riportati sul file e saranno immediatamente
957 visibili agli altri processi che mappano lo stesso
958 file.\footnotemark Il file su disco però non sarà
959 aggiornato fino alla chiamata di \func{msync} o
960 \func{unmap}), e solo allora le modifiche saranno
961 visibili per l'I/O convenzionale. Incompatibile
962 con \macro{MAP\_PRIVATE}. \\
963 \macro{MAP\_PRIVATE} & I cambiamenti sulla memoria mappata non vengono
964 riportati sul file. Ne viene fatta una copia
965 privata cui solo il processo chiamante ha
966 accesso. Le modifiche sono mantenute attraverso
967 il meccanismo del \textit{copy on write} e
968 salvate su swap in caso di necessità. Non è
969 specificato se i cambiamenti sul file originale
970 vengano riportati sulla regione
971 mappata. Incompatibile con \macro{MAP\_SHARED}. \\
972 \macro{MAP\_DENYWRITE} & In Linux viene ignorato per evitare
973 \textit{DoS}\index{DoS} (veniva usato per
974 segnalare che tentativi di scrittura sul file
975 dovevano fallire con \macro{ETXTBUSY}).\\
976 \macro{MAP\_EXECUTABLE}& Ignorato. \\
977 \macro{MAP\_NORESERVE} & Si usa con \macro{MAP\_PRIVATE}. Non riserva
978 delle pagine di swap ad uso del meccanismo di
979 \textit{copy on write} per mantenere le modifiche
980 fatte alla regione mappata, in
981 questo caso dopo una scrittura, se non c'è più
982 memoria disponibile, si ha l'emissione di
983 un \macro{SIGSEGV}. \\
984 \macro{MAP\_LOCKED} & Se impostato impedisce lo swapping delle pagine
986 \macro{MAP\_GROWSDOWN} & Usato per gli stack. Indica
987 che la mappatura deve essere effettuata con gli
988 indirizzi crecenti verso il basso.\\
989 \macro{MAP\_ANONYMOUS} & La mappatura non è associata a nessun file. Gli
990 argomenti \param{fd} e \param{offset} sono
991 ignorati.\footnotemark\\
992 \macro{MAP\_ANON} & Sinonimo di \macro{MAP\_ANONYMOUS}, deprecato.\\
993 \macro{MAP\_FILE} & Valore di compatibiità, deprecato.\\
996 \caption{Valori possibili dell'argomento \param{flag} di \func{mmap}.}
997 \label{tab:file_mmap_flag}
1000 \footnotetext{Dato che tutti faranno riferimento alle stesse pagine di
1002 \footnotetext{L'uso di questo flag con \macro{MAP\_SHARED} è
1003 stato implementato in Linux a partire dai kernel della serie 2.4.x.}
1005 Un file viene sempre mappato su multipli delle dimensioni di una pagina,
1006 qualora esso sia più corto la parte restante è riempita con zeri; eventuali
1007 scritture in quella zona di memoria non vengono riportate sul file. Se le
1008 dimensioni del file cambiano (esso viene esteso o troncato), non è specificato
1009 quale effetto viene a aversi sulle pagine di memoria che corrispondono alle
1010 regioni aggiunte o tolte.
1012 Si tenga presente che non tutti i file possono venire mappati in memoria, la
1013 mappatura infatti introduce una corrispondenza biunivoca fra una sezione di un
1014 file ed una sezione di memoria, pertanto si può parlare tanto di file mappato
1015 in memoria, quanto di memoria mappata su file. Questo comporta che ad esempio
1016 non è possibile mappare in memoria pipe, socket e fifo, per le quali non ha
1017 senso parlare di \textsl{sezione}. Lo stesso vale anche per alcuni file di
1018 dispositivo, che non dispongono della relativa operazione \var{mmap} (si
1019 ricordi quanto esposto in \secref{sec:file_vfs_work}), ma esistono anche casi
1020 (un esempio è l'interfaccia ponte PCI-VME del chip Universe) di dispositivi
1021 che sono utilizzabili praticamente solo con questa interfaccia.
1023 Passando attraverso una \func{fork} i file mappati in memoria vengono
1024 ereditati in maniera trasparente dal processo figlio, mantenendo gli stessi
1025 attributi avuti nel padre; così se si è usato \macro{MAP\_SHARED} padre e
1026 figlio accederanno allo stesso file in maniera condivisa, mentre se si è usato
1027 \macro{MAP\_PRIVATE} ciascuno di essi manterrà una sua versione privata
1028 indipendente. Non c'è invece nessun passaggio attraverso una \func{exec}, dato
1029 che quest'ultima sostituisce tutto lo spazio degli indirizzi di un processo
1030 con quello di un nuovo programma.
1032 Quando si effettua la mappatura di un file vengono pure modificati i tempi ad
1033 esso associati (si ricordi quanto esposto in \secref{sec:file_file_times}). Il
1034 valore di \var{st\_atime} può venir cambiato in qualunque istante a partire
1035 dal momento in cui la mappatura è stata effettuata: il primo riferimento ad
1036 una pagina mappata su un file aggiorna questo tempo. I valori di
1037 \var{st\_ctime} e \var{st\_mtime} possono venir cambiati solo quando si è
1038 consentita la scrittura sul file (cioè per un file mappato con
1039 \macro{PROT\_WRITE} e \macro{MAP\_SHARED}) e sono aggiornati dopo la scrittura
1040 o in corrispondenza di una eventuale \func{msync}.
1042 Dato per i file mappati in memoria le operazioni di I/O sono gestite
1043 direttamente dalla memoria virtuale, occorre essere consapevoli delle
1044 interazioni che possono esserci con operazioni effettuate con l'interfaccia
1045 standard dei file di \capref{sec:file_unix_interface}. Il problema è che una
1046 volta che si è mappato un file, le operazioni di lettura e scrittura saranno
1047 eseguite sulla memoria, e riportate su disco in maniera autonoma dal sistema
1048 della memoria virtuale.
1050 Pertanto se si modifica un file con l'interfaccia standard queste modifiche
1051 potranno essere visibili o meno a seconda del momento in cui la memoria
1052 virtuale leggerà dal disco in memoria quella sezione del file, perciò è del
1053 tutto indefinito il risultato della modifica nei confronti del contenuto della
1056 Se è, per quanto appena visto, sconsigliabile eseguire scritture su file
1057 attraverso l'interfaccia standard quando lo si è mappato in memoria, è invece
1058 possibile usare l'interfaccia standard per leggere un file mappato in memoria,
1059 purché si abbia una certa cura; infatti l'interfaccia dell'I/O mappato in
1060 memoria mette a disposizione la funzione \func{msync} per sincronizzare il
1061 contenuto della memoria mappata con il file su disco; il suo prototipo è:
1064 \headdecl{sys/mman.h}
1066 \funcdecl{int msync(const void *start, size\_t length, int flags)}
1068 Sincronizza i contenuti di una sezione di un file mappato in memoria.
1070 \bodydesc{La funzione restituisce 0 in caso di successo, e -1 in caso di
1071 errore nel qual caso \var{errno} viene impostata ai valori:
1073 \item[\macro{EINVAL}] O \param{start} non è multiplo di \macro{PAGESIZE},
1074 o si è specificato un valore non valido per \param{flags}.
1075 \item[\macro{EFAULT}] L'intervallo specificato non ricade in una zona
1076 precedentemente mappata.
1081 La funzione esegue la sincronizzazione di quanto scritto nella sezione di
1082 memoria indicata da \param{start} e \param{offset}, scrivendo le modifiche sul
1083 file (qualora questo non sia già stato fatto). Provvede anche ad aggiornare i
1084 relativi tempi di modifica. In questo modo si è sicuri che dopo l'esecuzione
1085 di \func{msync} le funzioni dell'interfaccia standard troveranno un contenuto
1086 del file aggiornato.
1088 L'argomento \param{flag} è specificato come maschera binaria composta da un OR
1089 dei valori riportati in \tabref{tab:file_mmap_rsync}, di questi però
1090 \macro{MS\_ASYNC} e \macro{MS\_SYNC} sono incompatibili; con il primo valore
1091 infatti la funzione si limita ad inoltrare la richiesta di sincronizzazione al
1092 meccanismo della memoria virtuale, ritornando subito, mentre con il secondo
1093 attende che la sincronizzazione sia stata effettivamente eseguita. Il terzo
1094 flag fa invalidare le pagine di cui si richiede la sincronizzazione per tutte
1095 le mappature dello stesso file, così che esse possano essere immediatamente
1096 aggiornate ai nuovi valori.
1101 \begin{tabular}[c]{|l|l|}
1103 \textbf{Valore} & \textbf{Significato} \\
1106 \macro{MS\_ASYNC} & Richiede la sincronizzazione.\\
1107 \macro{MS\_SYNC} & Attende che la sincronizzazione si eseguita.\\
1108 \macro{MS\_INVALIDATE}& Richiede che le altre mappature dello stesso file
1112 \caption{Valori dell'argomento \param{flag} di \func{msync}.}
1113 \label{tab:file_mmap_rsync}
1116 Una volta che si sono completate le operazioni di I/O si può eliminare la
1117 mappatura della memoria usando la funzione \func{munmap}, il suo prototipo è:
1120 \headdecl{sys/mman.h}
1122 \funcdecl{int munmap(void *start, size\_t length)}
1124 Rilascia la mappatura sulla sezione di memoria specificata.
1126 \bodydesc{La funzione restituisce 0 in caso di successo, e -1 in caso di
1127 errore nel qual caso \var{errno} viene impostata ai valori:
1129 \item[\macro{EINVAL}] L'intervallo specificato non ricade in una zona
1130 precedentemente mappata.
1135 La funzione cancella la mappatura per l'intervallo specificato attraverso
1136 \param{start} e \param{length}, ed ogni successivo accesso a tale regione
1137 causerà un errore di accesso in memoria. L'argomento \param{start} deve essere
1138 allineato alle dimensioni di una pagina di memoria, e la mappatura di tutte le
1139 pagine contenute (anche parzialmente) nell'intervallo indicato, verrà rimossa.
1140 Indicare un intervallo che non contiene pagine mappate non è un errore.
1142 Alla conclusione del processo, ogni pagina mappata verrà automaticamente
1143 rilasciata, mentre la chiusura del file descriptor non ha alcun effetto sulla
1144 mappatura della memoria.
1147 \section{Il file locking}
1148 \label{sec:file_locking}
1150 In \secref{sec:file_sharing} abbiamo preso in esame le modalità in cui un
1151 sistema unix-like gestisce la condivisione dei file da parte di processi
1152 diversi. In quell'occasione si è visto come, con l'eccezione dei file aperti
1153 in \textit{append mode}, quando più processi scrivono contemporaneamente sullo
1154 stesso file non è possibile determinare la sequenza in cui essi opereranno.
1156 Questo causa la possibilità di race condition\index{race condition}; in
1157 generale le situazioni più comuni sono due: l'interazione fra un processo che
1158 scrive e altri che leggono, in cui questi ultimi possono leggere informazioni
1159 scritte solo in maniera parziale o incompleta; o quella in cui diversi
1160 processi scrivono, mescolando in maniera imprevedibile il loro output sul
1163 In tutti questi casi il \textit{file locking} è la tecnica che permette di
1164 evitare le race condition, attraverso una serie di funzioni che permettono di
1165 bloccare l'accesso al file da parte di altri processi, così da evitare le
1166 sovrapposizioni, e garantire la atomicità delle operazioni di scrittura.
1169 \subsection{L'\textit{advisory locking}}
1170 \label{sec:file_record_locking}
1172 La prima modalità di file locking che è stata implementata nei sistemi
1173 unix-like è quella che viene usualmente chiamata \textit{advisory locking}, in
1174 quanto è il processo, e non il sistema, che si incarica di verificare se
1175 esiste una condizione di blocco per l'accesso ai file.
1180 \subsection{Il \textit{mandatory locking}}
1181 \label{sec:file_mand_locking}
1183 Il \textit{mandatory locking} è una opzione introdotta inizialmente in SVr4,
1184 per introdurre un file locking che come dice il nome, fosse effettivo
1185 indipendentemente dai controlli eseguiti da un processo. Con il
1186 \textit{mandatory locking} infatti è possibile far eseguire il blocco del file
1187 direttamente al sistema, così che anche qualora non si predisponessero le
1188 opportune verifiche nei processi, questo verrebbe comunque rispettato.
1190 Per poter utilizzare il \textit{mandatory locking} è stato introdotto un
1191 utilizzo particolare del bit \acr{suid}. Se si ricorda quanto esposto in
1192 \secref{sec:file_suid_sgid}), esso viene di norma utlizzato per cambiare
1193 l'\textit{effective user ID} con cui viene eseguito un programma, ed è
1194 pertanto sempre associato alla presenza del permesso di esecuzione. Impostando
1195 questo bit su un file senza permesso di esecuzione in un sistema che supporta
1196 il \textit{mandatory locking}, fa sì che quest'ultimo venga attivato per il
1197 file in questione. In questo modo una combinaizone dei permessi
1198 originariamente non contemplata, in quanto senza significato, diventa
1199 l'indicazione della presenza o meno del \textit{mandatory locking}.
1203 %%% Local Variables:
1205 %%% TeX-master: "gapil"