Provided by: manpages-fr-dev_4.15.0-9_all bug

NOM

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

SYNOPSIS

       #include <sys/mman.h>

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

       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.
              L'utilisation  de  MAP_ANONYMOUS avec MAP_SHARED n'est implémentée que depuis 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
              Don't interpret addr as a hint: place the mapping at  exactly  that  address.  addr
              must  be  suitably  aligned:  for most architectures a multiple of the page size is
              sufficient; however, some architectures may impose additional restrictions. If  the
              memory  region  specified  by  addr  and  length  overlaps  pages  of  any existing
              mapping(s), then the overlapped part of the existing mapping(s) will be  discarded.
              If the specified address cannot be used, mmap()  will fail.

              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 du noyau, 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)
              Allocate  the  mapping  using  "huge"  pages.  See  the  Linux  kernel  source file
              Documentation/admin-guide/mm/hugetlbpage.rst for further information,  as  well  as
              NOTES, below.

       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). Dans les noyaux
              antérieurs au 2.6, cet attribut n'avait d'effet que pour  les  projections  privées
              modifiables.

       MAP_POPULATE (depuis Linux 2.5.46)
              Populate  (prefault)  page  tables  for  a mapping. For a file mapping, this causes
              read-ahead on the file. This will help to reduce blocking on page faults later. The
              mmap()   call  doesn't fail if the mapping cannot be populated (for example, due to
              limitations  on  the  number  of  mapped  huge  pages  when   using   MAP_HUGETLB).
              MAP_POPULATE is supported for private mappings only since 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

       On success, mmap()  returns a pointer to the mapped area. On error, the  value  MAP_FAILED
       (that is, (void *) -1)  is returned, and errno is set to indicate the error.

       On  success,  munmap()  returns 0. On failure, it returns -1, and errno is set to indicate
       the error (probably to 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 contained none of MAP_PRIVATE, MAP_SHARED, or 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.

       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  The MAP_HUGETLB flag was specified, but the caller was not privileged (did not have
              the  CAP_IPC_LOCK  capability)  and is not a member of the sysctl_hugetlb_shm_group
              group; see the description of /proc/sys/vm/sysctl_hugetlb_shm_group in

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

CONFORMITÉ

       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 le noyau 2.4, cet appel
       système a été remplacé par mmap2(2). De nos jours, la fonction mmap() de la glibc  appelle
       mmap2(2) avec la bonne valeur pour offset.

BOGUES

       Sous  Linux,  il  n'y  a  aucune  garantie  comme  celles  indiquées plus haut à propos de
       MAP_NORESERVE. Par défaut, n'importe quel processus peut être tué à tout moment lorsque le
       système n'a plus de mémoire.

       Dans  les  noyaux  antérieurs à 2.6.7, le drapeau MAP_POPULATE n'avait d'effet que si prot
       était PROT_NONE.

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

       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 <sys/mman.h>
       #include <sys/stat.h>
       #include <fcntl.h>
       #include <stdio.h>
       #include <stdlib.h>
       #include <unistd.h>

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

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

           if (argc < 3 || argc > 4) {
               fprintf(stderr, "%s fichier offset [longueur]\n", argv[0]);
               exit(EXIT_FAILURE);
           }

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

           if (fstat(fd, &sb) == -1)           /* Pour obtenir la taille du fichier */
               handle_error("fstat");

           offset = atoi(argv[2]);
           pa_offset = offset & ~(sysconf(_SC_PAGE_SIZE) - 1);
               /* 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, pp. 128–129 et 389–391.

COLOPHON

       Cette page fait partie de la publication 5.13 du projet man-pages Linux.  Une  description
       du  projet et des instructions pour signaler des anomalies et la dernière version de cette
       page peuvent être trouvées à l'adresse https://www.kernel.org/doc/man-pages/.

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