dwww Home | Manual pages | Find package

mmap(2)                       System Calls Manual                      mmap(2)

NOM
       mmap,  munmap - Établir/supprimer une projection en mémoire (map/unmap)
       des fichiers ou des périphériques

BIBLIOTHÈQUE
       Bibliothèque C standard (libc, -lc)

SYNOPSIS
       #include <sys/mman.h>

       void *mmap(void addr[.length], size_t length, int prot, int flags,
                  int fd, off_t offset);
       int munmap(void addr[.length], size_t length);

       Consultez la section NOTES pour plus d'informations sur  les  exigences
       de la macro de test de fonctionnalité.

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 (qui doit être supérieure à 0).

       Si addr est NULL, le noyau choisit l'adresse (alignée sur une  page)  à
       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 (mais  tou-
       jours    supérieure    ou    égale    à    la   valeur   indiquée   par
       /proc/sys/vm/mmap_min_addr) et tente d'y créer la  projection.  Si  une
       projection  y existe déjà, le noyau prend une nouvelle adresse qui peut
       ou pas dépendre de l'indication. 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 oc-
       tets  à  partir  de la position offset dans le fichier (ou autre objet)
       correspondant au descripteur de fichier fd. offset doit  être  un  mul-
       tiple de la taille de la page renvoyée par sysconf(_SC_PAGE_SIZE).

       Après  le  retour  de l'appel mmap(), le descripteur de fichier fd peut
       être fermé immédiatement sans invalider la projection.

       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  in-
       accessible) soit d'un OU binaire entre les constantes suivantes :

       PROT_EXEC  Il est possible d'exécuter les pages.

       PROT_READ  Il est possible de lire les pages.

       PROT_WRITE Il est possible d'écrire les pages.

       PROT_NONE  Il n'est pas possible d'accéder aux pages.

   Le paramètre des attributs
       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 la même région
              et  (en  cas de projection file-backed) elles sont appliquées au
              fichier sous-jacent (pour contrôler précisément  le  moment  des
              mises à jour du fichier sous-jacent, il faut utiliser msync(2)).

       MAP_SHARED_VALIDATE (depuis Linux 4.15)
              Cet  attribut  apporte  le même comportement que MAP_SHARED sauf
              que les projections MAP_SHARED ignorent les  attributs  inconnus
              dans  flags.  Au contraire, lors de la création d'une projection
              en utilisant MAP_SHARED_VALIDATE, le noyau vérifie que tous  les
              attributs  passés  sont  connus et il fait échouer la projection
              avec l'erreur EOPNOTSUPP pour les attributs inconnus. Ce type de
              projection  est  aussi nécessaire pour pouvoir utiliser certains
              attributs de projection (comme MAP_SYNC).

       MAP_PRIVATE
              Créer une projection privée, utilisant la  méthode  de  copie  à
              l'écriture.  Les  modifications de la projection ne sont pas vi-
              sibles 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 dans la région projetée.

       MAP_SHARED  et  MAP_PRIVATE  sont  décrits  dans  POSIX.1-2001  et  PO-
       SIX.1-2008. MAP_SHARED_VALIDATE est une extension Linux.

       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'es-
              pace 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  fil  d'exécution  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 ; fourni pour une  compatibilité  avec
              d'autres implémentations.

       MAP_ANONYMOUS
              La  projection  n'est  prise  en  charge par aucun fichier ; son
              contenu est initialisé à 0. L'argument fd  est  ignoré ;  cepen-
              dant,  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. L'argument offset devrait
              être 0. La prise en charge de MAP_ANONYMOUS  avec  MAP_SHARED  a
              été ajoutée dans Linux 2.4.

       MAP_DENYWRITE
              Cet attribut est ignoré (autrefois — Linux 2.0 et antérieur — il
              signalait une tentative d'écriture dans le  fichier  sous-jacent
              et qui échouait avec l'erreur ETXTBUSY. Mais cela 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 correctement alignée : pour
              la plupart des architectures, un multiple de la taille  de  page
              suffit,  toutefois  certaines architectures imposent des limita-
              tions supplémentaires. Si la zone mémoire indiquée par  addr  et
              length  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.

              Les  logiciels  qui aspirent à la portabilité devraient utiliser
              l'attribut MAP_FIXED prudemment, en gardant à l'esprit que l'as-
              pect  exact des projections de mémoire du processus est autorisé
              à changer significativement entre les versions de Linux,  de  la
              glibc et du système d'exploitation. Lisez attentivement le point
              sur cet attribut dans les NOTES !

       MAP_FIXED_NOREPLACE (depuis Linux 4.17)
              Cet attribut offre un comportement  identique  à  MAP_FIXED  par
              rapport  à  l'application  de addr, mais il s'en distingue en ce
              que MAP_FIXED_NOREPLACE n’écrase jamais une plage projetée exis-
              tante. Si la plage demandée entre en conflit avec une projection
              existante, cet appel échoue avec l'erreur EEXIST.  Cet  attribut
              peut donc être utilisé comme une façon d'essayer de projeter une
              plage d'adresses de manière atomique  (vis-à-vis  d'autres  fils
              d'exécutions) :  un thread réussira, tous les autres signaleront
              un échec.

              Remarquez que les anciens noyaux qui ne reconnaissent pas  l'at-
              tribut MAP_FIXED_NOREPLACE se rabattront généralement (en détec-
              tant une collision avec une projection existante) sur un type de
              comportement  « sans  MAP_FIXED » :  ils  renverront une adresse
              différente de celle demandée.  Les  logiciels  rétro-compatibles
              devront  donc vérifier l'adresse renvoyée vis-à-vis de l'adresse
              demandée.

       MAP_GROWSDOWN
              Cet attribut est utilisé pour les piles. Il indique au noyau  le
              système  de  mémoire virtuelle vers lequel la projection devrait
              descendre dans la mémoire. L'adresse renvoyée est une page infé-
              rieure à la zone de mémoire créée dans l'espace d'adressage vir-
              tuel du processus. La modification d'une adresse dans la page de
              « garde »  sous  la projection fera agrandir la projection d’une
              page. Cette croissance peut se répéter jusqu'à ce que la  taille
              de  la  projection dans la page atteigne l’extrémité haute de la
              projection plus basse suivante, point où la modification  de  la
              page de « garde » donnera un signal SIGSEGV.

       MAP_HUGETLB (depuis Linux 2.6.32)
              Allouer  la projection à l'aide de « pages immenses ». Consultez
              le fichier Documentation/vm/hugetlbpage.txt des sources du noyau
              Linux pour plus d'informations ainsi que les NOTES ci-dessous.

       MAP_HUGE_2MB, MAP_HUGE_1GB (depuis Linux 3.8)
              Utilisé  avec  MAP_HUGETLB pour sélectionner d'autres tailles de
              pages immenses (hugetlb) (respectivement 2 Mo et 1 Go)  sur  les
              systèmes qui gèrent plusieurs tailles de page hugetlb.

              Plus  généralement,  la taille de la page immense souhaitée peut
              être configurée en encodant le logarithme de base 2 de la taille
              de  la  page désirée dans les six bits situés sur MAP_HUGE_SHIFT
              (une valeur de zéro dans ce champ de bit fournit  la  taille  de
              page  immense  par  défaut ;  vous  pouvez  connaître celle-ci à
              l'aide du champ Hugepagesize qui apparaît  dans  /proc/meminfo).
              Ainsi, les deux constantes ci-dessus sont définies comme suit :

                  #define MAP_HUGE_2MB    (21 << MAP_HUGE_SHIFT)
                  #define MAP_HUGE_1GB    (30 << MAP_HUGE_SHIFT)

              Vous pouvez connaître l'intervalle de tailles des pages immenses
              gérées  par  le  système  en  listant  les  sous-répertoires  de
              /sys/kernel/mm/hugepages.

       MAP_LOCKED (depuis Linux 2.5.37)
              Marquer  la  région projetée pour qu'elle soit verrouillée de la
              même manière que mlock(2). Cette implémentation essaiera de rem-
              plir  (prefault)  toute  la plage mais l'appel mmap() n’échouera
              pas avec ENOMEM si cela échoue. Des erreurs  énormes  pourraient
              donc  se  produire  ultérieurement. La sémantique n'est donc pas
              aussi robuste que mlock(2).  Vous  devriez  utiliser  mmap()  et
              mlock(2)  si  d'énormes  erreurs  ne  sont pas acceptables après
              l'initialisation de la  projection.  L'attribut  MAP_LOCKED  est
              ignoré sur les anciens noyaux.

       MAP_NONBLOCK (depuis Linux 2.5.46)
              Cet attribut 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  ef-
              fet.  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 projec-
              tion.  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).
              Avant Linux 2.6, cet attribut n'avait d'effet que pour les  pro-
              jections privées modifiables.

       MAP_POPULATE (depuis Linux 2.5.46)
              Remplir (prefault) les tables de pages pour une projection. Pour
              une projection de fichier, cela provoque une  lecture  anticipée
              du  fichier.  Les accès ultérieurs à la projection ne seront pas
              bloqués par des erreurs de pages. L'appel mmap n'échoue  pas  si
              la  projection  ne peut pas être remplie (par exemple à cause de
              limitation sur le nombre  de  pages  immenses  mappées  lors  de
              l'utilisation  de  MAP_HUGETLB). La prise en charge de MAP_POPU-
              LATE avec  les  projections  privées  a  été  ajoutée  dans  Li-
              nux 2.6.23.

       MAP_STACK (depuis Linux 2.6.27)
              Allouer  la projection à une adresse qui convient à la pile d'un
              processus ou d'un thread.

              Cet attribut n'est pas opérationnel pour  l'instant  sur  Linux.
              Mais  son  utilisation  permet  aux  applications  de  s'assurer
              qu'elles le gèreront de manière transparente s'il est implémenté
              dans  le  futur.  Ainsi, il est utilisé dans l'implémentation de
              threading de la glibc pour accepter le fait que certaines archi-
              tectures  pourront  (plus tard) nécessiter un traitement spécial
              pour allouer des piles. Une autre raison d'utiliser cet attribut
              est la portabilité : MAP_STACK existe et a un effet sur d'autres
              systèmes (comme certains BSD).

       MAP_SYNC (depuis Linux 4.15)
              Cet attribut  n'est  possible  qu'avec  le  type  de  projection
              MAP_SHARED_VALIDATE ; les projections de type MAP_SHARED ignore-
              ront silencieusement cet attribut. Il n'est pris en  charge  que
              pour  des  fichiers gérant le DAX (projection directe de mémoire
              persistante). Pour les autres  fichiers,  créer  une  projection
              avec cet attribut provoquera une erreur EOPNOTSUPP.

              Les  projections  de  fichier  partagé  ayant cet attribut four-
              nissent une garantie que tant que la mémoire est  projetée  avec
              accès  en  écriture dans l'espace d'adressage du processus, elle
              sera visible dans le même fichier et au même endroit même  après
              un plantage ou un redémarrage du système. Couplé à l'utilisation
              des instructions adéquates du processeur, cela offre aux  utili-
              sateurs  de  telles  projections  une  manière  plus efficace de
              rendre des modifications de données persistantes.

       MAP_UNINITIALIZED (depuis Linux 2.6.33)
              Ne pas effacer 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  PO-
       SIX.1-2001  et  POSIX.1-2008. Cependant, la plupart des systèmes gèrent
       aussi MAP_ANONYMOUS (ou son synonyme MAP_ANON).

   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 auto-
       matiquement  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 la page  (mais  ce
       n'est pas obligatoire pour length). Toutes les pages contenant une par-
       tie 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.

VALEUR RENVOYÉE
       En cas de succès, mmap() renvoie un pointeur sur la zone  projetée.  En
       cas  d'échec,  la valeur MAP_FAILED (c'est-à-dire (void *) -1) est ren-
       voyée et errno est défini pour indiquer l'erreur.

       S'il réussit, munmap() renvoie 0. En cas d'échec,  -1  est  renvoyé  et
       errno est défini pour indiquer l'erreur (probablement EINVAL).

ERREURS
       EACCES Le  descripteur ne correspond pas à un fichier normal ou une de-
              mande de projection de fichier a été demandée mais fd n'est  pas
              ouvert  en  lecture,  ou  une  demande  de  projection  partagée
              MAP_SHARED avec protection PROT_WRITE a  été  demandée  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é).

       EEXIST MAP_FIXED_NOREPLACE  était  indiqué  dans flags et la plage cou-
              verte par addr et length est  en  conflit  avec  une  projection
              existante.

       EINVAL addr  ou  length ou offset sont non valables (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 contenait ni MAP_PRIVATE, ni  MAP_SHARED,  ni  MAP_SHA-
              RED_VALIDATE.

       ENFILE La  limite  du  nombre total de fichiers ouverts pour le système
              entier a été atteinte.

       ENODEV Le système de fichiers sous-jacent ne gère pas la projection  en
              mémoire.

       ENOMEM Aucune mémoire disponible.

       ENOMEM Le  nombre  maximal  de projections du processus serait dépassé.
              Cette erreur peut aussi se produire pour  munmap()  lors  de  la
              suppression  d'une  projection d'une région au milieu d'une pro-
              jection existante, puisque cela provoque deux régions  plus  pe-
              tites de chaque côté de la région à supprimer.

       ENOMEM (Depuis  Linux  4.7) La limite RLIMIT_DATA du processus, décrite
              dans getrlimit(2), serait dépassée.

       ENOMEM addr n'est pas apprécié parce qu'il dépasse l'espace d'adressage
              virtuel du processeur

       EOVERFLOW
              Sur  architecture  32 bits  avec  l'extension  de  fichiers très
              grands (c'est-à-dire utilisant un off_t sur 64 bits) : le nombre
              de pages utilisées pour length plus le nombre de pages utilisées
              pour offset dépasserait unsigned long (32 bits).

       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.

       EPERM  La lecture a été interrompue par un signal ; consultez fnctl(2).

       EPERM  L'attribut MAP_HUGETLB était indiqué,  mais  l'appelant  n'était
              pas  priviliégié  (il  n'avait  pas la capacité CAP_IPC_LOCK) et
              n'appartient pas  au  groupesysctl_hugetlb_shm_group ;  voir  la
              desription de /proc/sys/vm/sysctl_hugetlb_shm_group dans

       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 page du tampon au-delà de la fin du fi-
              chier projeté. Pour une explication  du  traitement  des  octets
              dans  la  page correspondant à la fin du fichier projeté n'étant
              pas un multiple de la taille de la page, voir les NOTES.

ATTRIBUTS
       Pour une explication des termes utilisés dans cette section,  consulter
       attributes(7).

       ┌─────────────────────────────────────┬──────────────────────┬─────────┐
       │InterfaceAttributValeur  │
       ├─────────────────────────────────────┼──────────────────────┼─────────┤
       │mmap(), munmap()                     │ Sécurité des threads │ MT-Safe │
       └─────────────────────────────────────┴──────────────────────┴─────────┘

STANDARDS
       POSIX.1-2001, POSIX.1-2008, SVr4, 4.4BSD.

       Sur  les  systèmes POSIX sur lesquels mmap(), msync(2) et munmap() sont
       disponibles, _POSIX_MAPPED_FILES  est  définie  dans  <unistd.h>  comme
       étant une valeur supérieure à 0 (consultez aussi sysconf(3)).

NOTES
       La mémoire obtenue par mmap est préservée au travers d'un fork(2), avec
       les mêmes attributs.

       Un fichier est projeté en multiples de de la taille de la page. 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  corres-
       pondant aux zones ajoutées ou supprimées ne sont pas précisés.

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

       Certaines  constantes de flags sont définies seulement si des macros de
       test de fonctionnalités adaptées sont définies (potentiellement par dé-
       faut) :  _DEFAULT_SOURCE  avec  la  glibc  2.19  ou supérieure, ou bien
       _BSD_SOURCE ou _SVID_SOURCE dans la glibc 2.19 et antérieure (la  défi-
       nition  de  _GNU_SOURCE  suffit également, et son usage aurait été plus
       logique, puisque ces attributs sont tous spécifiques à Linux). Les  at-
       tributs  adéquats  sont :  MAP_32BIT,  MAP_ANONYMOUS  (et  son synonyme
       MAP_ANON),  MAP_DENYWRITE,  MAP_EXECUTABLE,  MAP_FILE,   MAP_GROWSDOWN,
       MAP_HUGETLB,  MAP_LOCKED, MAP_NONBLOCK, MAP_NORESERVE, MAP_POPULATE, et
       MAP_STACK.

       Une application peut déterminer les pages d'une projection se  trouvant
       dans le tampon/le cache de page en utilisant mincore(2).

   Utilisation sûre de MAP_FIXED
       La  seule  utilisation  sûre de MAP_FIXED est quand la plage d'adresses
       indiquée par addr et length a été préalablement réservée  en  utilisant
       une  autre projection ; sans quoi l'utilisation de MAP_FIXED est hasar-
       deuse car elle supprime brutalement des projections  préexistantes,  ce
       qui  facilite  la corruption par un processus multithread de son propre
       espace d'adressage.

       Par exemple, supposons qu'un thread A cherche dans /proc/<pid>/maps une
       plage  d'adresses  inutilisée  où  il  peut  se  projeter  en utilisant
       MAP_FIXED, tandis qu'un thread B acquiert en même temps tout ou  partie
       de  cette  même  plage  d'adresses. Quand le thread A utilisera ensuite
       mmap(MAP_FIXED), il va de fait  écraser  la  projection  créée  par  le
       thread B. Dans ce scénario, le thread B ne doit pas créer de projection
       directement ; un appel de bibliothèque qui, en  interne,  utilise  dlo-
       pen(3)  pour  charger  d'autres bibliothèques partagées, est suffisant.
       L'appel dlopen(3) projettera la bibliothèque dans l'espace  d'adressage
       du processus. De plus, presque tous les appels de bibliothèques peuvent
       être implémentés d'une manière qui ajoute des  projections  de  mémoire
       aux  espaces  d'adressage,  à  l'aide de cette technique ou en allouant
       simplement de la mémoire. Parmi les  exemples,  figurent  brk(2),  mal-
       loc(3),      pthread_create(3)     et     les     bibliothèques     PAM
       ⟨http://www.linux-pam.org⟩.

       Depuis Linux 4.17, un programme multithreadé peut  utiliser  l'attribut
       MAP_FIXED_NOREPLACE pour éviter le risque décrit ci-dessus quand on es-
       saie de créer une projection à une adresse fixe non  réservée  par  une
       projection préexistante.

   Modifications d'horodatage pour les projections prises en charge par un fi-
       chier
       Pour les projections prises en charge 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  met-
       tra 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  pro-
       jetée,  et avant l'éventuel msync(2) suivant avec l'attribut MS_SYNC ou
       MS_ASYNC.

   Projections de pages immenses (Huge TLB)
       Pour les projections qui utilisent des pages  immenses,  les  exigences
       des  attributs de mmap() et de munmap() diffèrent quelque peu de celles
       pour des projections qui utilisent la taille native des pages  du  sys-
       tème.

       Pour  mmap(),  offset doit être un multiple de la taille de la page im-
       mense sous-jacente. Le système aligne automatiquement length pour qu'il
       soit un multiple de la taille de la page immense sous-jacente.

       Pour  munmap(), addr et length doivent être tous deux un multiple de la
       taille de la page immense sous-jacente.

   différences entre bibliothèque C et noyau
       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 Linux 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.

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.

       Avant Linux 2.6.7, l'attribut MAP_POPULATE n'avait d'effet que si  prot
       était PROT_NONE.

       SUSv3  indique  que  mmap() devrait échouer si length est 0. Cependant,
       avant Linux 2.6.12, mmap() réussissait dans ce cas : aucune  projection
       n'était  créée,  et l'appel renvoyait addr. Depuis Linux 2.6.12, mmap()
       échoue avec le code d'erreur EINVAL si length est nul.

       POSIX spécifie que le système devrait toujours remplir de zéros  toutes
       les  pages  incomplètes  à la fin de l'objet et que le système n'écrira
       jamais de modification de l'objet au-delà de sa fin. Sous  Linux,  lors
       de  l'écriture  de  données vers ce genre de pages incomplètes après la
       fin de l'objet, les données restent dans le cache de  page  même  après
       que  le fichier soit fermé et déprojeté, et même si les données ne sont
       jamais écrites vers le  fichier  lui-même,  les  projections  suivantes
       pourraient  voir  le  contenu modifié. Dans certains cas, cela pourrait
       être corrigé en appelant msync(2)  avant  la  déprojection.  Cependant,
       cela  ne fonctionne pas sur tmpfs(5) (par exemple en utilisant l'inter-
       face de mémoire partagée POSIX documentée dans shm_overview(7)).

EXEMPLES
       Le programme suivant affiche la partie du fichier, précisé par le  pre-
       mier  argument de la ligne de commande, sur la sortie standard. Les oc-
       tets qui seront affichés sont précisés à partir d'un  offset  (déplace-
       ment)  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  uti-
       lise write(2) pour afficher les octets voulus.

   Source du programme
       #include <fcntl.h>
       #include <stdio.h>
       #include <stdlib.h>
       #include <sys/mman.h>
       #include <sys/stat.h>
       #include <unistd.h>

       #define handle_error(msg) \
           do { perror(msg); exit(EXIT_FAILURE); } while (0)

       int
       main(int argc, char *argv[])
       {
           int          fd;
           char         *addr;
           off_t        offset, pa_offset;
           size_t       length;
           ssize_t      s;
           struct stat  sb;

           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);
               /* la position de mmap() doit être alignée sur la 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);
           }

           munmap(addr, length + offset - pa_offset);
           close(fd);

           exit(EXIT_SUCCESS);
       }

VOIR AUSSI
       ftruncate(2),  getpagesize(2),  memfd_create(2),  mincore(2), mlock(2),
       mmap2(2), mprotect(2), mremap(2), msync(2), remap_file_pages(2),  setr-
       limit(2), shmat(2), userfaultfd(2), shm_open(3), shm_overview(7)

       Dans   proc(5),   les   descriptions   des  fichiers  /proc/[pid]/maps,
       /proc/[pid]/map_files et /proc/[pid]/smaps.

       B.O. Gallmeister, POSIX.4, O'Reilly, p. 128–129 et 389–391.

TRADUCTION
       La traduction française de cette page de manuel a été créée par  Chris-
       tophe  Blaess  <https://www.blaess.fr/christophe/>, Stéphan Rafin <ste-
       phan.rafin@laposte.net>, Thierry Vignaud <tvignaud@mandriva.com>, Fran-
       çois  Micaux, Alain Portal <aportal@univ-montp2.fr>, Jean-Philippe Gué-
       rard <fevrier@tigreraye.org>, Jean-Luc  Coulon  (f5ibh)  <jean-luc.cou-
       lon@wanadoo.fr>,  Julien  Cristau <jcristau@debian.org>, Thomas Huriaux
       <thomas.huriaux@gmail.com>, Nicolas François  <nicolas.francois@centra-
       liens.net>,  Florentin  Duneau <fduneau@gmail.com>, Simon Paillard <si-
       mon.paillard@resel.enst-bretagne.fr>,   Denis   Barbier    <barbier@de-
       bian.org>,  David  Prévot  <david@tilapin.org> et Jean-Philippe MENGUAL
       <jpmengual@debian.org>

       Cette traduction est une documentation libre ; veuillez vous reporter à
       la        GNU        General       Public       License       version 3
       ⟨https://www.gnu.org/licenses/gpl-3.0.html⟩ concernant  les  conditions
       de copie et de distribution. Il n'y a aucune RESPONSABILITÉ LÉGALE.

       Si  vous découvrez un bogue dans la traduction de cette page de manuel,
       veuillez envoyer un message à ⟨debian-l10n-french@lists.debian.org⟩.

Pages du manuel de Linux 6.03   5 février 2023                         mmap(2)

Generated by dwww version 1.15 on Sat Jun 29 00:40:20 CEST 2024.