Provided by: manpages-fr-dev_4.27.0-1_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'est pas membre du groupe sysctl_hugetlb_shm_group ; voir la desription
              de /proc/sys/vm/sysctl_hugetlb_shm_group dans proc_sys(5).

       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 │
       └──────────────────────────────────────────────────────────────────────┴──────────────────────┴─────────┘

VERSIONS

       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.

   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.

STANDARDS

       POSIX.1-2008.

HISTORIQUE

       POSIX.1-2001, 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.

       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.

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 <sys/types.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 position du fichier [longueur]\n", argv[0]);
               exit(EXIT_FAILURE);
           }

           fd = open(argv[1], O_RDONLY);
           if (fd == -1)
               handle_error("open");

           if (fstat(fd, &sb) == -1)           /* To obtain file size */
               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, "la position est au-delà de 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;
                       /* Ne peut pas afficher d'octets situés après la fin du fichier */

           } else {    /* Pas d'affichage de longueur arg ==> à 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 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.9.1                    15 juin 2024                                           mmap(2)