Loading

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);

       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   cete
              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 « d’énormes pages ». Voyez le
              fichier source du  noyau  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. Voir é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.

       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).

       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.

       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 dhorodatage 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 (voir 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 projection 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é).

CONFORMITÉ

       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. (Voir aussi
       sysconf(3).)

NOTES

       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);
       } /* main */

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.23  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

       Cette  page  de  manuel a été traduite par Thierry Vignaud <tvignaud AT
       mandriva DOT com> en 2002, puis a été mise  à  jour  par  Alain  Portal
       <aportal  AT  univ-montp2  DOT fr> jusqu’en 2006, et mise à disposition
       sur http://manpagesfr.free.fr/.

       Les mises à jour et corrections de la version présente dans Debian sont
       directement gérées par Julien Cristau <jcristau@debian.org> et l’équipe
       francophone de traduction de Debian.

       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> ».