-Dato che passando attraverso una \func{fork} lo spazio di indirizzi viene
-copiato integralmente, i file mappati in memoria verranno ereditati in maniera
-trasparente dal processo figlio, mantenendo gli stessi attributi avuti nel
-padre; così se si è usato \const{MAP\_SHARED} padre e figlio accederanno allo
-stesso file in maniera condivisa, mentre se si è usato \const{MAP\_PRIVATE}
-ciascuno di essi manterrà una sua versione privata indipendente. Non c'è
-invece nessun passaggio attraverso una \func{exec}, dato che quest'ultima
-sostituisce tutto lo spazio degli indirizzi di un processo con quello di un
-nuovo programma.
-
-Quando si effettua la mappatura di un file vengono pure modificati i tempi ad
-esso associati (di cui si è trattato in sez.~\ref{sec:file_file_times}). Il
-valore di \var{st\_atime} può venir cambiato in qualunque istante a partire
-dal momento in cui la mappatura è stata effettuata: il primo riferimento ad
-una pagina mappata su un file aggiorna questo tempo. I valori di
-\var{st\_ctime} e \var{st\_mtime} possono venir cambiati solo quando si è
-consentita la scrittura sul file (cioè per un file mappato con
-\const{PROT\_WRITE} e \const{MAP\_SHARED}) e sono aggiornati dopo la scrittura
-o in corrispondenza di una eventuale \func{msync}.
-
-Dato per i file mappati in memoria le operazioni di I/O sono gestite
-direttamente dalla \index{memoria~virtuale}memoria virtuale, occorre essere
-consapevoli delle interazioni che possono esserci con operazioni effettuate
-con l'interfaccia standard dei file di cap.~\ref{cha:file_unix_interface}. Il
-problema è che una volta che si è mappato un file, le operazioni di lettura e
-scrittura saranno eseguite sulla memoria, e riportate su disco in maniera
-autonoma dal sistema della memoria virtuale.
-
-Pertanto se si modifica un file con l'interfaccia standard queste modifiche
-potranno essere visibili o meno a seconda del momento in cui la memoria
-virtuale trasporterà dal disco in memoria quella sezione del file, perciò è
-del tutto imprevedibile il risultato della modifica di un file nei confronti
-del contenuto della memoria su cui è mappato.
-
-Per questo, è sempre sconsigliabile eseguire scritture su file attraverso
-l'interfaccia standard, quando lo si è mappato in memoria, è invece possibile
-usare l'interfaccia standard per leggere un file mappato in memoria, purché si
-abbia una certa cura; infatti l'interfaccia dell'I/O mappato in memoria mette
-a disposizione la funzione \funcd{msync} per sincronizzare il contenuto della
-memoria mappata con il file su disco; il suo prototipo è:
-\begin{functions}
- \headdecl{unistd.h}
- \headdecl{sys/mman.h}
-
- \funcdecl{int msync(const void *start, size\_t length, int flags)}
-
- Sincronizza i contenuti di una sezione di un file mappato in memoria.
-
- \bodydesc{La funzione restituisce 0 in caso di successo, e -1 in caso di
- errore nel qual caso \var{errno} assumerà uno dei valori:
- \begin{errlist}
- \item[\errcode{EINVAL}] o \param{start} non è multiplo di
- \const{PAGE\_SIZE}, o si è specificato un valore non valido per
- \param{flags}.
- \item[\errcode{EFAULT}] l'intervallo specificato non ricade in una zona
- precedentemente mappata.
- \end{errlist}
- }
-\end{functions}
-
-La funzione esegue la sincronizzazione di quanto scritto nella sezione di
-memoria indicata da \param{start} e \param{offset}, scrivendo le modifiche sul
-file (qualora questo non sia già stato fatto). Provvede anche ad aggiornare i
-relativi tempi di modifica. In questo modo si è sicuri che dopo l'esecuzione
-di \func{msync} le funzioni dell'interfaccia standard troveranno un contenuto
-del file aggiornato.
-
-\begin{table}[htb]
- \centering
- \footnotesize
- \begin{tabular}[c]{|l|l|}
- \hline
- \textbf{Valore} & \textbf{Significato} \\
- \hline
- \hline
- \const{MS\_ASYNC} & Richiede la sincronizzazione.\\
- \const{MS\_SYNC} & Attende che la sincronizzazione si eseguita.\\
- \const{MS\_INVALIDATE}& Richiede che le altre mappature dello stesso file
- siano invalidate.\\
- \hline
- \end{tabular}
- \caption{Le costanti che identificano i bit per la maschera binaria
- dell'argomento \param{flag} di \func{msync}.}
- \label{tab:file_mmap_rsync}
-\end{table}
-
-L'argomento \param{flag} è specificato come maschera binaria composta da un OR
-dei valori riportati in tab.~\ref{tab:file_mmap_rsync}, di questi però
-\const{MS\_ASYNC} e \const{MS\_SYNC} sono incompatibili; con il primo valore
-infatti la funzione si limita ad inoltrare la richiesta di sincronizzazione al
-meccanismo della memoria virtuale, ritornando subito, mentre con il secondo
-attende che la sincronizzazione sia stata effettivamente eseguita. Il terzo
-flag fa invalidare le pagine di cui si richiede la sincronizzazione per tutte
-le mappature dello stesso file, così che esse possano essere immediatamente
-aggiornate ai nuovi valori.
-
-Una volta che si sono completate le operazioni di I/O si può eliminare la
-mappatura della memoria usando la funzione \funcd{munmap}, il suo prototipo è:
-\begin{functions}
- \headdecl{unistd.h}
- \headdecl{sys/mman.h}
-
- \funcdecl{int munmap(void *start, size\_t length)}
-
- Rilascia la mappatura sulla sezione di memoria specificata.
-
- \bodydesc{La funzione restituisce 0 in caso di successo, e -1 in caso di
- errore nel qual caso \var{errno} assumerà uno dei valori:
- \begin{errlist}
- \item[\errcode{EINVAL}] l'intervallo specificato non ricade in una zona
- precedentemente mappata.
- \end{errlist}
- }
-\end{functions}
-
-La funzione cancella la mappatura per l'intervallo specificato con
-\param{start} e \param{length}; ogni successivo accesso a tale regione causerà
-un errore di accesso in memoria. L'argomento \param{start} deve essere
-allineato alle dimensioni di una pagina, e la mappatura di tutte le pagine
-contenute anche parzialmente nell'intervallo indicato, verrà rimossa.
-Indicare un intervallo che non contiene mappature non è un errore. Si tenga
-presente inoltre che alla conclusione di un processo ogni pagina mappata verrà
-automaticamente rilasciata, mentre la chiusura del file descriptor usato per
-il \textit{memory mapping} non ha alcun effetto su di esso.
-
-Lo standard POSIX prevede anche una funzione che permetta di cambiare le
-protezioni delle pagine di memoria; lo standard prevede che essa si applichi
-solo ai \textit{memory mapping} creati con \func{mmap}, ma nel caso di Linux
-la funzione può essere usata con qualunque pagina valida nella memoria
-virtuale. Questa funzione è \funcd{mprotect} ed il suo prototipo è:
-\begin{functions}
-% \headdecl{unistd.h}
- \headdecl{sys/mman.h}
-
- \funcdecl{int mprotect(const void *addr, size\_t len, int prot)}
-
- Modifica le protezioni delle pagine di memoria comprese nell'intervallo
- specificato.
-
- \bodydesc{La funzione restituisce 0 in caso di successo, e -1 in caso di
- errore nel qual caso \var{errno} assumerà uno dei valori:
- \begin{errlist}
- \item[\errcode{EINVAL}] il valore di \param{addr} non è valido o non è un
- multiplo di \const{PAGE\_SIZE}.
- \item[\errcode{EACCESS}] l'operazione non è consentita, ad esempio si è
- cercato di marcare con \const{PROT\_WRITE} un segmento di memoria cui si
- ha solo accesso in lettura.
-% \item[\errcode{ENOMEM}] non è stato possibile allocare le risorse
-% necessarie all'interno del kernel.
-% \item[\errcode{EFAULT}] si è specificato un indirizzo di memoria non
-% accessibile.
- \end{errlist}
- ed inoltre \errval{ENOMEM} ed \errval{EFAULT}.
- }
-\end{functions}
-