Provided by: manpages-fr-dev_4.19.0-7_all bug

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  toujours
       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 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 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 inaccessible)  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 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 dans la région projetée.

       MAP_SHARED    et   MAP_PRIVATE   sont   décrits   dans   POSIX.1-2001   et   POSIX.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'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 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é ; 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. 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 limitations 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'aspect 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 existante. 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'attribut
              MAP_FIXED_NOREPLACE se rabattront généralement (en détectant 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  virtuel  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 remplir (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 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). Avant Linux 2.6,
              cet attribut n'avait d'effet que pour les projections 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_POPULATE avec les projections privées a été ajoutée dans
              Linux 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  architectures  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 ignoreront 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 fournissent 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 utilisateurs 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  POSIX.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 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  la  page  (mais  ce  n'est  pas
       obligatoire  pour  length).  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.

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  renvoyé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 demande  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  couverte  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_SHARED_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  projection existante, puisque cela provoque deux régions
              plus petites 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 fichier  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
       correspondant 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éfinition  de _GNU_SOURCE suffit également, et son usage aurait été plus
       logique, puisque ces attributs sont tous spécifiques  à  Linux).  Les  attributs  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 hasardeuse 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  dlopen(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),    malloc(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 essaie  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 fichier
       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 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 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 système.

       Pour mmap(), offset doit être un multiple de la taille de la page immense 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'interface 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 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.

   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),    setrlimit(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  Christophe  Blaess
       <https://www.blaess.fr/christophe/>,  Stéphan  Rafin  <stephan.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.coulon@wanadoo.fr>,   Julien    Cristau    <jcristau@debian.org>,    Thomas    Huriaux
       <thomas.huriaux@gmail.com>, Nicolas François <nicolas.francois@centraliens.net>, Florentin
       Duneau <fduneau@gmail.com>, Simon Paillard <simon.paillard@resel.enst-bretagne.fr>,  Denis
       Barbier  <barbier@debian.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⟩.