NOM¶
mmap, munmap - Établir/supprimer une projection en mémoire (map/unmap)
  des fichiers ou des périphériques
SYNOPSIS¶
#include <sys/mman.h>
 
void *mmap(void *addr, size_t length, int prot, int flags,
           int fd, off_t offset);
int munmap(void *addr, size_t length);
DESCRIPTION¶
mmap() crée une nouvelle projection dans l'espace d'adressage
  virtuel du processus appelant. L'adresse de démarrage de la nouvelle
  projection est indiquée dans 
addr. Le paramètre 
length
  indique la longueur de la projection.
 
Si 
addr est NULL, le noyau choisit l'adresse à laquelle
  démarrer la projection ; c'est la méthode la plus portable pour
  créer une nouvelle projection. Si 
addr n'est pas NULL, le noyau le
  considère comme une indication sur l'endroit où placer la
  projection ; sous Linux, elle sera placée à une frontière
  de page proche. L'adresse de la nouvelle projection est renvoyée comme
  résultat de l'appel.
 
Le contenu d'une projection de fichier (par opposition à une projection
  anonyme ; voir ci-dessous 
MAP_ANONYMOUS) est initialisé avec
  
length octets à partir de la position 
offset dans le
  fichier (ou autre objet) correspondant au descripteur de fichier 
fd.
  
offset doit être un multiple de la taille de page, renvoyée
  par 
sysconf(_SC_PAGE_SIZE).
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 détermine si les modifications de la
  projection sont visibles depuis les autres processus projetant la même
  région, et si les modifications sont appliquées au fichier
  sous-jacent. Ce comportement est déterminé en incluant exactement
  une des valeurs suivantes dans 
flags :
  - MAP_SHARED
 
  - Partager la projection. Les modifications de la projection
      sont visibles dans les autres processus qui projettent ce fichier, et sont
      appliquées au fichier sous-jacent. En revanche, ce dernier n'est pas
      nécessairement mis à jour tant qu'on n'a pas appelé
      msync(2) ou munmap().
 
  - MAP_PRIVATE
 
  - Créer une projection privée, utilisant la
      méthode de copie à l'écriture. Les modifications de la
      projection ne sont pas visibles depuis les autres processus projetant le
      même fichier, et ne modifient pas le fichier lui-même. Il n'est
      pas précisé si les changements effectués dans le fichier
      après l'appel mmap() seront visibles.
 
Ces deux attributs sont décrits dans POSIX.1-2001.
 
De plus, zéro ou plus des valeurs suivantes peuvent être incluses dans
  
flags (avec un OU binaire) :
  - MAP_32BIT (depuis Linux 2.4.20, 2.6)
 
  - Placer la projection dans les deux premiers gigaoctets de
      l'espace d'adressage du processus. Cet attribut n'est pris en charge que
      sous x86-64, pour les programmes 64 bits. Il a été
      ajouté pour permettre à la pile d'un thread d'être
      allouée dans les deux premiers gigaoctets de mémoire, afin
      d'améliorer les performances des changements de contexte sur les
      premiers processeurs 64 bits. Les processeurs x86-64 modernes n'ont
      plus ces problèmes de performance, donc l'utilisation de cet attribut
      n'est pas nécessaire sur ces systèmes. L'attribut
      MAP_32BIT est ignoré quand MAP_FIXED est
      positionné.
 
  - MAP_ANON
 
  - Synonyme de MAP_ANONYMOUS.
    Déconseillé.
 
  - MAP_ANONYMOUS
 
  - La projection n'est supportée par aucun fichier ;
      son contenu est initialisé à 0. Les arguments fd et
      offset sont ignorés ; cependant, certaines
      implémentations demandent que fd soit -1 si
      MAP_ANONYMOUS (ou MAP_ANON) est utilisé, et les
      applications portables doivent donc s'en assurer. Cet attribut,
      utilisé en conjonction de MAP_SHARED, n'est
      implémenté que depuis Linux 2.4.
 
  - 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 par déni
      de service.)
 
  - MAP_EXECUTABLE
 
  - Cet attribut est ignoré.
 
  - MAP_FILE
 
  - Attribut pour compatibilité. Ignoré.
 
  - MAP_FIXED
 
  - Ne pas considérer addr comme une
      indication : n'utiliser que l'adresse indiquée. addr doit
      être un multiple de la taille de page. Si la zone mémoire
      indiquée par addr et len recouvre des pages d'une
      projection existante, la partie recouverte de la projection existante sera
      ignorée. Si l'adresse indiquée ne peut être utilisée,
      mmap() échouera. Il est déconseillé d'utiliser cette
      option, car requérir une adresse fixe pour une projection n'est pas
      portable.
 
  - 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_HUGETLB (depuis Linux 2.6.32)
 
  - Allouer la projection à l'aide de « pages
      immenses ». Consultez le fichier source du noyau Linux
      Documentation/vm/hugetlbpage.txt pour plus d'informations.
 
  - MAP_LOCKED (depuis Linux 2.5.37)
 
  - Verrouille la page projetée en mémoire à la
      manière de mlock(2). Cet attribut est ignoré sur les
      noyaux plus anciens.
 
  - MAP_NONBLOCK (depuis Linux 2.5.46)
 
  - N'a de sens qu'en conjonction avec MAP_POPULATE. Ne
      pas effectuer de lecture anticipée : créer seulement les
      entrées de tables de page pour les pages déjà
      présentes en RAM. Depuis Linux 2.6.23, cet attribut fait que
      MAP_POPULATE n'a aucun effet. Un jour la combinaison de
      MAP_POPULATE et MAP_NONBLOCK pourra être
      implémentée de nouveau.
 
  - MAP_NORESERVE
 
  - 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. Consultez
      également la description du fichier
      /proc/sys/vm/overcommit_memory dans la page proc(5). Dans
      les noyaux antérieurs à 2.6, cet attribut n'avait d'effet que
      pour les projections privées modifiables.
 
  - MAP_POPULATE (depuis Linux 2.5.46)
 
  - Remplit les tables de pages pour une projection. Pour une
      projection de fichier, ceci s'effectue par une lecture anticipée du
      fichier. Les accès ultérieurs à la projection ne seront pas
      bloqués par des fautes de pages. MAP_POPULATE n'est
      géré pour les projections privées que depuis
      Linux 2.6.23.
 
  - MAP_STACK (depuis Linux 2.6.27)
 
  - Alloue la projection à une adresse qui convient pour
      la pile d'un processus ou d'un thread. Cet attribut n'a pour l'instant
      aucun effet, mais est utilisé par l'implémentation des threads
      de la glibc de telle sorte que si certaines architectures nécessitent
      un traitement particulier pour l'allocation de la pile, leur prise en
      charge par la suite par la glibc pourra être implémentée de
      façon transparente.
 
  - MAP_UNINITIALIZED (depuis Linux 2.6.33)
 
  - N'efface pas les pages anonymes. Cet attribut n'a pour
      l'instant un effet que si le noyau a été configuré avec
      l'option CONFIG_MMAP_ALLOW_UNINITIALIZED. À cause des
      implications sur la sécurité, cette option n'est normalement
      active que sur des périphériques embarqués
      (c'est-à-dire avec des périphériques avec lesquels il est
      possible d'avoir un contrôle total de la mémoire
    utilisateur).
 
Parmi les attributs ci-dessus, seul 
MAP_FIXED est spécifié dans
  POSIX.1-2001. Cependant, la plupart des systèmes gèrent aussi
  
MAP_ANONYMOUS (ou son synonyme 
MAP_ANON).
Certains systèmes utilisent les attributs supplémentaires
  
MAP_AUTOGROW, 
MAP_AUTORESRV, 
MAP_COPY et
  
MAP_LOCAL.
La mémoire obtenue par 
mmap est préservée au travers d'un
  
fork(2), avec les mêmes 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.
munmap()¶
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 
addr doit être un multiple de la taille de page. Toutes
  les pages contenant une partie de l'intervalle indiqué 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.
Modifications d'horodatage pour les projections supportées
  par un fichier¶
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 cela 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(2) suivant avec attribut 
MS_SYNC ou 
MS_ASYNC.
VALEUR RENVOYÉE¶
mmap() renvoie un pointeur sur la zone de mémoire, s'il
  réussit. En cas d'échec il retourne la valeur 
MAP_FAILED
  (c.‐à‐d. 
(void *) -1) et 
errno
  contient le code d'erreur. 
munmap() renvoie 0 s'il réussit. En cas
  d'échec, -1 est renvoyé et 
errno contient le code d'erreur
  (probablement 
EINVAL).
ERREURS¶
  - EACCES
 
  - Le descripteur ne correspond pas à un fichier normal,
      ou on demande une projection privée MAP_PRIVATE mais fd
      n'est pas ouvert en lecture, ou on demande une projection partagée
      MAP_SHARED avec protection PROT_WRITE, mais fd n'est
      pas ouvert en lecture et écriture ( O_RDWR). Ou encore
      PROT_WRITE est demandé, mais le fichier est ouvert en ajout
      seulement.
 
  - EAGAIN
 
  - Le fichier est verrouillé, ou trop de pages ont
      été verrouillées en mémoire (consultez
      setrlimit(2)).
 
  - EBADF
 
  - fd n'est pas un descripteur de fichier valable (et
      MAP_ANONYMOUS n'était pas précisé).
 
  - EINVAL
 
  - addr ou length ou offset sont
      invalides (par exemple : zone trop grande, ou non alignée sur
      une frontière de page).
 
  - EINVAL
 
  - (depuis Linux 2.6.12) length est nul.
 
  - EINVAL
 
  - flags ne contient ni MAP_PRIVATE ni
      MAP_SHARED, ou les contient tous les deux.
 
  - ENFILE
 
  - La limite du nombre total de fichiers ouverts sur le
      système a été atteinte.
 
  - ENODEV
 
  - Le système de fichiers sous‐jacent ne supporte
      pas la projection en mémoire.
 
  - ENOMEM
 
  - Pas assez de mémoire, ou le nombre maximal de
      projections par processus a été dépassé.
 
  - EPERM
 
  - L'argument prot a demandé PROT_EXEC mais
      la zone appartient à un fichier sur un système de fichiers
      monté sans permission d'exécution.
 
  - ETXTBSY
 
  - MAP_DENYWRITE a été réclamé mais
      fd est ouvert en écriture.
 
L'accès à une zone de projection peut déclencher les signaux
  suivants :
  - SIGSEGV
 
  - Tentative d'écriture dans une zone en lecture
    seule.
 
  - SIGBUS
 
  - Tentative d'accès à une portion de la zone qui ne
      correspond pas au fichier (par exemple après la fin du fichier, y
      compris lorsqu'un autre processus l'a tronqué).
 
SVr4, BSD 4.4, POSIX.1-2001.
DISPONIBILITɶ
Sur les systèmes POSIX sur lesquels 
mmap(), 
msync(2) et
  
munmap() sont disponibles, la constante symbolique
  
_POSIX_MAPPED_FILES est définie dans 
<unistd.h> comme
  étant une valeur supérieure à 0. (Consultez aussi
  
sysconf(3).)
NOTES¶
Cette page décrit l'interface fournie par la fonction 
mmap() de la
  glibc. Initialement, cette fonction appelait un appel système du
  même nom. Depuis le noyau 2.4, cet appel système a été
  remplacé par 
mmap2(2). De nos jours, la fonction 
mmap() de
  la glibc appelle 
mmap2(2) avec la bonne valeur pour 
offset.
 
Sur certaines architectures matérielles (par exemple, i386),
  
PROT_WRITE implique 
PROT_READ. Cela dépend de
  l'architecture si 
PROT_READ implique 
PROT_EXEC ou non. Les
  programmes portables doivent toujours indiquer 
PROT_EXEC s'ils veulent
  exécuter du code dans la projection.
 
La manière portable de créer une projection est de spécifier
  
addr à 0 (NULL), et d'omettre 
MAP_FIXED dans 
flags.
  Dans ce cas, le système choisit l'adresse de la projection ;
  l'adresse est choisie de manière à ne pas entrer en conflit avec une
  projection existante et de ne pas être nulle. Si l'attribut
  
MAP_FIXED est indiqué et si 
addr vaut 0 (NULL), l'adresse
  projetée sera zéro (NULL).
BOGUES¶
Sous Linux, il n'y a aucune garantie comme celles indiquées plus haut
  à propos de 
MAP_NORESERVE. Par défaut, n'importe quel
  processus peut être tué à tout moment lorsque le système
  n'a plus de mémoire.
 
Dans les noyaux antérieurs à 2.6.7, le drapeau 
MAP_POPULATE
  n'avait d'effet que si 
prot était 
PROT_NONE.
 
SUSv3 indique que 
mmap() devrait échouer si 
length est 0.
  Cependant, avec les versions de Linux antérieures à 2.6.12,
  
mmap() réussissait dans ce cas : aucune projection
  n'était créée, et l'appel renvoyait 
addr. Depuis le
  noyau 2.6.12, 
mmap() échoue avec le code d'erreur 
EINVAL si
  
length est nul.
EXEMPLE¶
Le programme suivant affiche la partie du fichier, précisé par le
  premier argument de la ligne de commande, sur la sortie standard. Les octets
  qui seront affichés sont précisés à partir d'un offset
  (déplacement) et d'une longueur en deuxième et troisième
  paramètre. Le code fait une projection mémoire des pages
  nécessaires du fichier puis utilise 
write(2) pour afficher les
  octets voulus.
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define handle_error(msg) \
    do { perror(msg); exit(EXIT_FAILURE); } while (0)
int
main(int argc, char *argv[])
{
    char *addr;
    int fd;
    struct stat sb;
    off_t offset, pa_offset;
    size_t length;
    ssize_t s;
    if (argc < 3 || argc > 4) {
        fprintf(stderr, "%s fichier offset [longueur]\n", argv[0]);
        exit(EXIT_FAILURE);
    }
    fd = open(argv[1], O_RDONLY);
    if (fd == -1)
        handle_error("open");
    if (fstat(fd, &sb) == -1)           /* Pour obtenir la taille du fichier */
        handle_error("fstat");
    offset = atoi(argv[2]);
    pa_offset = offset & ~(sysconf(_SC_PAGE_SIZE) - 1);
        /* l'offset pour mmap() doit être aligné sur une page */
    if (offset >= sb.st_size) {
        fprintf(stderr, "L'offset dépasse la fin du fichier\n");
        exit(EXIT_FAILURE);
    }
    if (argc == 4) {
        length = atoi(argv[3]);
        if (offset + length > sb.st_size)
            length = sb.st_size - offset;
                /* Impossible d'afficher les octets en dehors du fichier */
    } else {    /* Pas de paramètre longueur
                   ==> affichage jusqu'à la fin du fichier */
        length = sb.st_size - offset;
    }
    addr = mmap(NULL, length + offset - pa_offset, PROT_READ,
                MAP_PRIVATE, fd, pa_offset);
    if (addr == MAP_FAILED)
        handle_error("mmap");
    s = write(STDOUT_FILENO, addr + offset - pa_offset, length);
    if (s != length) {
        if (s == -1)
            handle_error("write");
        fprintf(stderr, "écriture partielle");
        exit(EXIT_FAILURE);
    }
    exit(EXIT_SUCCESS);
}
VOIR AUSSI¶
getpagesize(2), 
mincore(2), 
mlock(2), 
mmap2(2),
  
mprotect(2), 
mremap(2), 
msync(2),
  
remap_file_pages(2), 
setrlimit(2), 
shmat(2),
  
shm_open(3), 
shm_overview(7)
 
B.O. Gallmeister, POSIX.4, O'Reilly, pp. 128–129 et 389–391.
COLOPHON¶
Cette page fait partie de la publication 3.44 du projet 
man-pages Linux.
  Une description du projet et des instructions pour signaler des anomalies
  peuvent être trouvées à l'adresse
  <
http://www.kernel.org/doc/man-pages/>.
TRADUCTION¶
Depuis 2010, cette traduction est maintenue à l'aide de l'outil po4a
  <
http://po4a.alioth.debian.org/> par l'équipe de traduction
  francophone au sein du projet perkamon
  <
http://perkamon.alioth.debian.org/>.
Thierry Vignaud (2002), Alain Portal
  <
http://manpagesfr.free.fr/> (2006). Julien Cristau et
  l'équipe francophone de traduction de Debian (2006-2009).
Veuillez signaler toute erreur de traduction en écrivant à
  <debian-l10n-french@lists.debian.org> ou par un rapport de bogue sur le
  paquet 
manpages-fr.
Vous pouvez toujours avoir accès à la version anglaise de ce document
  en utilisant la commande «  
man -L C
  <section>  <page_de_man> ».