mmap, munmap - Établir / supprimer une projection en mémoire (map / unmap) des fichiers ou des périphériques.
La fonction
mmap
demande la projection en mémoire de
length
octets commençant à la position
offset
depuis un fichier (ou un autre objet) indiqué par le descripteur
fd,
de préférence à l'adresse pointée par
start.
Cette adresse n'est qu'une préférence, généralement 0.
La véritable adresse où l'objet est projeté est renvoyée par la
fonction
mmap,
et n'est jamais nulle.
L'argument
prot
indique la protection que l'on désire pour cette zone de mémoire, et ne
doit pas entrer en conflit avec le mode d'ouverture du fichier.
Il s'agit soit de
PROT_NONE
(le contenu de la mémoire est inaccessible) soit d'un OU binaire entre
les constantes suivantes :
- PROT_EXEC
-
On peut exécuter du code dans la zone mémoire.
- PROT_READ
-
On peut lire le contenu de la zone mémoire
- PROT_WRITE
-
On peut écrire dans la zone mémoire.
- PROT_NONE
-
Les pages ne peuvent pas être accédées.
Le paramètre
flags
indique le type de fichier projeté, les options de projection, et si
les modifications faites sur la portion projetée sont privées ou doivent
être partagées avec les autres références. Les options sont :
- MAP_FIXED
-
N'utiliser que l'adresse indiquée. Si c'est impossible,
mmap
échouera. Si MAP_FIXED est spécifié
start
doit être un multiple de la longueur de page. Il est déconseillé d'utiliser
cette option.
- MAP_SHARED
-
Partager la projection avec tout autre processus utilisant l'objet.
L'écriture dans la zone est équivalente à une écriture dans le fichier. En revanche
ce dernier n'est pas nécessairement mis à jour tant qu'on n'a pas appelé
msync(2)
ou
munmap(2).
- MAP_PRIVATE
-
Créer une projection privée, utilisant la méthode de copie à l'écriture.
L'écriture dans la zone ne modifie pas le fichier. Il n'est pas précisé
si les changements effectués dans le fichier après l'appel
mmap
seront visibles.
Vous devez indiquer soit MAP_SHARED, soit MAP_PRIVATE.
Les trois attributs ci-dessus sont décrits dans POSIX.1b (anciennement POSIX.4)
et SUSv2. Linux propose également des attributs non standards :
- MAP_DENYWRITE
-
Cet attribut est ignoré.
(Autrefois, une tentative d'écriture dans le fichier sous-jacent échouait avec
l'erreur ETXTBUSY. Mais ceci permettait des attaques de déni de service).
- MAP_EXECUTABLE
-
Cet attribut est ignoré.
- MAP_NORESERVE
-
(Utilisé conjointement à MAP_PRIVATE). Ne pas réserver d'espace de swap pour
les pages de cette projection. Une telle réservation garantit que l'on puisse
modifier les zones soumises à une copie-en-écriture. Sans réservation, on peut
recevoir un signal SIGSEGV durant une écriture, s'il n'y a plus de place
disponible.
- MAP_LOCKED
-
(Depuis Linux 2.5.37) Verrouille la page projetée en mémoire à la manière de
mlock().
Cet attribut est ignoré sur les noyaux plus anciens.
- MAP_GROWSDOWN
-
Utilisé pour les piles. Indique au système de gestion de la mémoire virtuelle
que la projection doit s'étendre en croissant vers le bas de la mémoire.
- MAP_ANONYMOUS
-
La projection n'est supportée par aucun fichier. Les arguments
fd
et
offset
sont ignorés. Cet attributs, utilisé en conjonction de MAP_SHARE
est implémenté depuis Linux 2.4.
- MAP_ANON
-
Alias de MAP_ANONYMOUS. Déconseillé.
- MAP_FILE
-
Attribut pour compatibilité. Ignoré.
- MAP_32BIT
-
Faire la projection dans les premiers 2Go de l'espace d'adressage du processus.
Ignoré si
MAP_FIXED
est présent. Cet attribut n'est supporté que sur x86-64 pour les programmes 64-bits.
Certains systèmes utilisent les attributs supplémentaires MAP_AUTOGROW,
MAP_AUTORESRV, MAP_COPY, and MAP_LOCAL.
fd
doit être un descripteur de fichier valide, sauf si on utilise MAP_ANONYMOUS,
auquel cas cet argument est ignoré.
L'argument
offset
doit normalement être un multiple de la taille de page renvoyée par l'appel
getpagesize(2).
La mémoire obtenue par
mmap
est préservée lors d'un
fork(2),
avec les même attributs.
La projection doit avoir une taille multiple de celle des pages. Pour un fichier
dont la longueur n'est pas un multiple de la taille de page, la mémoire restante
est remplie de zéros lors de la projection, et les écritures dans cette zone
n'affectent pas le fichier. Les effets de la modification de la taille du fichier sous-jacent
sur les pages correspondant aux zones ajoutées ou supprimées ne sont pas précisés.
L'appel-système
munmap
détruit la projection dans la zone de mémoire spécifiée, et s'arrange pour
que toute référence ultérieure à cette zone mémoire déclenche une
erreur d'adressage. La projection est aussi automatiquement détruite lorsque
le processus se termine. À l'inverse, la fermeture du descripteur de fichier
ne supprime pas la projection.
L'adresse
start
doit être un multiple de la taille de page. Tous les pages contenant une partie
de l'intervalle indiquées sont libérées, et tout accès ultérieur
déclenchera SIGSEGV. Aucune erreur n'est détectée si l'intervalle
indiqué ne contient pas de page projetée.
Pour les projections supportées par un fichier, le champ
st_atime
du fichier peut être mis à jour à tout moment entre l'appel
mmap()
et le munmap() correspondant. Le premier accès dans la page projetée
mettra le champ à jour si ce n'a pas été déjà fait.
Les champs
st_ctime
et
st_mtime
pour un fichier projeté avec PROT_WRITE et MAP_SHARED seront mis à jour après
une écriture dans la région projetée, et avant l'éventuel
msync()
suivant avec attribut MS_SYNC ou MS_ASYNC.
SVr4, POSIX.1b (anciennement POSIX.4), BSD 4.4, SUSv2.
SVr4 documente les codes d'erreur supplémentaires ENXIO et ENODEV.
SUSv2 documente les codes d'erreur supplémentaires EMFILE et EOVERFLOW.
MAP_32BIT
est une extension Linux.
Christophe Blaess, 1996-2003.