mmap   Début   Suivant   Sommaire   Préc.page.lue   Accueil
Section: Manuel du programmeur Linux (2)
Updated: 5 juin 2008
Sommaire  



NOM   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil
mmap, munmap - Établir/supprimer une projection en mémoire (map/unmap) des fichiers ou des périphériques  



SYNOPSIS   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil
#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);
 



DESCRIPTION   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil
mmap() crée une nouvelle projection dans l'espace d'adressage virtuel du processus appelant. L'adresse de départ de la nouvelle projection est indiquée dans addr. L'argument spécifie la longueur de la projection.

Si addr est NULL, le noyau choisit l'adresse à laquelle créer la projection ; c'est la méthode la plus portable pour créer une nouvelle projection. Si addr n'est pas NULL, le noyau considère comme un conseil l'endroit où placer la projection ; sous Linux, la projection sera créée à la prochaine plus haute frontière de page. L'adresse de la nouvelle projection est renvoyée comme résultat de l'appel.

Le contenu d'une projection de fichier (contrairement à une projection anonyme ; voir MAP_ANONYMOUS plus loin), est initialisé avec length octets démarrant au décalage offset dans le fichier (ou autre objet) référencé par le descripteur de fichiers fd. offset doit être un multiple de la taille de page telle qu'elle est renvoyée par sysconf(_SC_PAGE_SIZE).

L'argument prot indique la protection mémoire que l'on désire pour cette projection, et ne doit pas entrer en conflit avec le mode d'ouverture du fichier. Il s'agit soit de PROT_NONE (le contenu de la mémoire est inaccessible) soit d'un OU binaire entre les constantes suivantes :

PROT_EXEC
On peut exécuter du code dans la zone mémoire.
PROT_READ
On peut lire le contenu de la zone mémoire.
PROT_WRITE
On peut écrire dans la zone mémoire.
PROT_NONE
Les pages ne peuvent pas être accédées.

Le paramètre flags si les mises à jour de la projection sont visibles par les autres processus projetant la même région et si les mises à jour sont reportées au fichier sous-jacent. Ce comportement est déterminé en incluant exactement une des valeurs suivantes dans flags :

MAP_SHARED
Partager cette projection. Les mises à jour de la projection sont visibles par les autres processus qui projettent ce fichier, et sont reportées au fichier sous-jacent. En revanche, ce dernier n'est pas nécessairement mis à jour tant qu'on n'a pas appelé msync(2) ou munmap().
MAP_PRIVATE
Créer une projection privée, utilisant la méthode de copie à l'écriture. Les mises à jour de la projection ne sont pas visibles par les autres processus projetant le même fichier et ne sont pas reportées au fichier sous-jacent. Il n'est pas précisé si les changements effectués dans le fichier après l'appel mmap() seront visibles.

Ces attributs sont décrits dans POSIX.1-2001.

De plus, zéro ou plus des valeurs suivantes peuvent être ajoutées dans flags avec un OU binaire :

MAP_32BIT
Faire la projection dans les premiers 2 Go de l'espace d'adressage du processus. Ignoré si MAP_FIXED est présent. Cet attribut n'est supporté que sur x86-64, pour les programmes 64 bits.
MAP_ANON
Synonyme de MAP_ANONYMOUS. Déconseillé.
MAP_ANONYMOUS
La projection n'est supportée par aucun fichier. Son contenu est initialisé à zéro. Les arguments fd et offset sont ignorés. toutefois, certaines implémentations demandent que fd vaille -1 si MAP_ANONYMOUS (ou MAP_ANON) est spécifié et les applications portables doivent s'en assurer. L'utilisation de MAP_ANONYMOUS en conjonction de MAP_SHARED, n'est supporté sous Linux que depuis le noyau 2.4.
MAP_DENYWRITE
Cet attribut est ignoré. (Autrefois, une tentative d'écriture dans le fichier sous-jacent échouait avec l'erreur ETXTBUSY. Mais ceci permettait des attaques de déni de service).
MAP_EXECUTABLE
Cet attribut est ignoré.
MAP_FILE
Attribut pour compatibilité. Ignoré.
MAP_FIXED
Ne pas interpréter addr comme une indication : placer la projection exactement à cette adresse. addr doit être un multiple de la taille de page. Si la zone mémoire indiquée par addr et len recouvrent des pages d'une projection existante, les parties recouvertes de la projection existantes seront ignorées. Si l'adresse spécifiée ne peut être utilisée, mmap() échouera. Parce que requérir une adresse fixe pour un projection est moins portable, il est déconseillé d'utiliser cette option.
MAP_GROWSDOWN
Utilisé pour les piles. Indique au système de gestion de la mémoire virtuelle que la projection doit s'étendre en croissant vers le bas de la mémoire.
MAP_LOCKED (depuis Linux 2.5.37)
Verrouille la page projetée en mémoire à la manière de mlock(2). Cet attribut est ignoré sur les noyaux plus anciens.
MAP_NONBLOCK (depuis Linux 2.5.46)
N'a de sens qu'en conjonction avec MAP_POPULATE. Ne pas efectuer 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 rend MAP_POPULATE inactif. Un jour, la combination de MAP_POPULATE et MAP_NONBLOCK pourrait être réimplémentées.
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 la projection. Sans réservation, on peut recevoir un signal SIGSEGV durant une écriture, s'il n'y a plus de mémoire physique disponible. Voir également la discussion sur le fichier /proc/sys/vm/overcommit_memory dans proc(5). Dans les noyaux précédant le 2.6, cet attribut n'avait d'effet que pour les projections privées.
MAP_POPULATE (depuis Linux 2.5.46)
Remplit les tables de pages pour une projection de fichier. Pour une projection de fichier, cela provoque une lecture anticipée sur le fichier. Les accès ultérieurs à la projection ne seront pas bloqués par des fautes de pages. MAP_POPULATE n'est pris en charge que pour les projections privées depuis Linux 2.6.23.

Parmi les attributs précédents, seul MAP_FIXED est spécifié dans POSIX.1-2001. Toutefois, la plupart des systèmes prennent également en charge MAP_ANONYMOUS (ou son synonyme MAP_ANON).

Certains systèmes utilisent les attributs supplémentaires MAP_AUTOGROW, MAP_AUTORESRV, MAP_COPY et MAP_LOCAL.

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

La projection doit avoir une taille multiple de celle des pages. Pour un fichier dont la longueur n'est pas un multiple de la taille de page, la mémoire restante est remplie de zéros lors de la projection, et les écritures dans cette zone n'affectent pas le fichier. Les effets de la modification de la taille du fichier sous-jacent sur les pages correspondant aux zones ajoutées ou supprimées ne sont pas précisés.

 




munmap()   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil
L'appel système munmap() détruit la projection dans la zone de mémoire spécifiée, et s'arrange pour que toute référence ultérieure à cette zone mémoire déclenche une erreur d'adressage. La projection est aussi automatiquement détruite lorsque le processus se termine. À l'inverse, la fermeture du descripteur de fichier ne supprime pas la projection.

L'adresse addr doit être un multiple de la taille de page. Tous les pages contenant une partie de l'intervalle indiqué sont libérées, et tout accès ultérieur déclenchera SIGSEGV. Aucune erreur n'est détectée si l'intervalle indiqué ne contient pas de page projetée.

 




Modifications d'horodatage pour les projections supportées par un fichier   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil
Pour les projections supportées par un fichier, le champ st_atime du fichier peut être mis à jour à tout moment entre l'appel mmap() et le munmap() correspondant. Le premier accès dans la page projetée mettra le champ à jour si cela n'a pas été déjà fait.

Les champs st_ctime et st_mtime pour un fichier projeté avec PROT_WRITE et MAP_SHARED seront mis à jour après une écriture dans la région projetée, et avant l'éventuel msync(3) suivant avec attribut MS_SYNC ou MS_ASYNC.  




VALEUR RENVOYÉE   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil
mmap() renvoie un pointeur sur la zone de mémoire, s'il réussit. En cas d'échec il retourne la valeur MAP_FAILED (c'est-à-dire (void *) -1) et errno contient le code d'erreur.

munmap() renvoie 0 s'il réussit. En cas d'échec, -1 est renvoyé et errno contient le code d'erreur (probablement EINVAL).  




ERREURS   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil
EACCES
Le descripteur ne correspond pas à un fichier normal, ou on demande une projection privée MAP_PRIVATE mais fd n'est pas ouvert en lecture, ou on demande une projection partagée MAP_SHARED avec protection PROT_WRITE, mais fd n'est pas ouvert en lecture et écriture (O_RDWR). Ou encore PROT_WRITE est demandé, mais le fichier est ouvert en ajout seulement.
EAGAIN
Le fichier est verrouillé, ou trop de pages ont été verrouillées en mémoire (voir setrlimit(2)).
EBADF
fd n'est pas un descripteur de fichier valide (et MAP_ANONYMOUS n'était pas précisé).
EINVAL
addr, length ou offset sont invalides. (Par exemple : zone trop grande, ou non alignée sur une frontière de page).
EINVAL
(Depuis Linux 2.6.12), length valait 0.
EINVAL
flags contenait soit MAP_PRIVATE, soit MAP_SHARED, soit les deux.
ENFILE
La limite du nombre total de fichiers ouverts sur le système a été atteinte.
ENODEV
Le système de fichiers sous-jacent ne supporte pas la projection en mémoire.
ENOMEM
pas assez de mémoire, ou le nombre maximal de projection par processus a été dépassé.
EPERM
L'argument prot a demandé PROT_EXEC mais la zone appartient à un fichier sur un système de fichiers monté sans permissions d'exécution.
ETXTBSY
MAP_DENYWRITE a été réclamé mais fd est ouvert en écriture.

L'accès à une zone de projection peut déclencher les signaux suivants :

SIGSEGV
Tentative d'écriture dans une zone en lecture seule.
SIGBUS
Tentative d'accès à une portion de la zone qui ne correspond pas au fichier (par exemple après la fin du fichier, y compris lorsqu'un autre fichier l'a tronqué).
 



CONFORMITÉ   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil
SVr4, BSD 4.4, POSIX.1-2001.  



DISPONIBILITÉ   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil
Sur les systèmes POSIX sur lesquels mmap(), msync(2) et munmap() sont disponibles, la constante symbolique _POSIX_MAPPED_FILES est définie dans <unistd.h> comme étant une valeur supérieure à 0. (Voir aussi sysconf(3).)  



NOTES   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil
Depuis le noyau 2.4, cet appel système a été remplacé par mmap2(2). Aujourd'hui, la fonction enveloppe mmap() de la glibc invoque mmap2(2) avec une valeur offset convenablement ajustée.

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 est 0 (NULL), l'adresse projetée sera zéro (NULL).  




BOGUES   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil
Sous Linux, il n'y a aucune garantie comme celle suggérée sous MAP_NORESERVE. Par défaut, tout processus peut être tué à tout moment lorsque le système s'exécute en dehors de de l'espace mémoire.

Dans les noyaux antérieurs au 2.6.7, l'attribut MAP_POPULATE n'a d'effet que si prot a la valeur PROT_NONE.

SUSv3 spécifie que mmap() devrait échoué si length vaut 0. Toutefois, dans les noyaux précédents le 2.6.12, mmap() réussissait dans ce cas : aucun mappage n'était créé et l'appel renvoyait addr. Depuis le noyau 2.6.12, mmap() échoue avec l'erreur EINVAL dans ce cas.  




EXEMPLE   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

Le programme suivant affiche sur la sortie standard une partie du fichier fourni en tant que premier argument de la ligne de commande. La plage d'octets à afficher est indiquée par les valeurs d'offset et de longueur fournies comme deuxième et troisième arguments de la ligne de commande. Le programme crée une projection mémoire des pages du fichier nécessaires et utilise write(2) pour écrire les octets souhaités.


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

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

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

    if (argc < 3 || argc > 4) {
        fprintf(stderr, "%s file offset [length]\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);
        /* offset for mmap() must be page aligned */

    if (offset >= sb.st_size) {
        fprintf(stderr, "offset is past end of file\n");
        exit(EXIT_FAILURE);
    }

    if (argc == 4) {
        length = atoi(argv[3]);
        if (offset + length > sb.st_size)
            length = sb.st_size - offset;
                /* Can't display bytes past end of file */

    } else {    /* No length arg ==> display to end of file */
        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, "partial write");
        exit(EXIT_FAILURE);
    }

    exit(EXIT_SUCCESS);
} /* main */
 



VOIR AUSSI   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil
getpagesize(2), mincore(2), mlock(2), mmap2(2), mprotect(2), mremap(2), msync(2), remap_file_pages(2), setrlimit(2), shmat(2), shm_open(3)
B.O. Gallmeister, POSIX.4, O'Reilly, pp. 119-124 et 365-369.  



TRADUCTION   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

Ce document est une traduction réalisée par Christophe Blaess <http://www.blaess.fr/christophe/> le 14 octobre 1996 et révisée le 6 juin 2008.

L'équipe de traduction a fait le maximum pour réaliser une adaptation française de qualité. La version anglaise la plus à jour de ce document est toujours consultable via la commande : « LANG=C man 2 mmap ». N'hésitez pas à signaler à l'auteur ou au traducteur, selon le cas, toute erreur dans cette page de manuel.


 



Sommaire   Début   Suivant   Sommaire   Préc.page.lue   Accueil
NOM
SYNOPSIS
DESCRIPTION
munmap()
Modifications d'horodatage pour les projections supportées par un fichier
VALEUR RENVOYÉE
ERREURS
CONFORMITÉ
DISPONIBILITÉ
NOTES
BOGUES
EXEMPLE
VOIR AUSSI
TRADUCTION

Table des mots clés   Début   Suivant   Sommaire   Préc.page.lue   Accueil
EACCESERREURS
EAGAINERREURS
EBADFERREURS
EINVALERREURS
ENFILEERREURS
ENODEVERREURS
ENOMEMERREURS
EPERMERREURS
ETXTBSYERREURS
MAP_32BITDESCRIPTION
MAP_ANONDESCRIPTION
MAP_ANONYMOUSDESCRIPTION
MAP_DENYWRITEDESCRIPTION
MAP_EXECUTABLEDESCRIPTION
MAP_FILEDESCRIPTION
MAP_FIXEDDESCRIPTION
MAP_GROWSDOWNDESCRIPTION
MAP_LOCKED (depuis Linux 2.5.37)DESCRIPTION
MAP_NONBLOCK (depuis Linux 2.5.46)DESCRIPTION
MAP_NORESERVEDESCRIPTION
MAP_POPULATE (depuis Linux 2.5.46)DESCRIPTION
MAP_PRIVATEDESCRIPTION
MAP_SHAREDDESCRIPTION
PROT_EXECDESCRIPTION
PROT_NONEDESCRIPTION
PROT_READDESCRIPTION
PROT_WRITEDESCRIPTION
SIGBUSERREURS
SIGSEGVERREURS



Ce document a été créé par man2html suivi de man2html.pl, le 17/10/2008 17:50:53, en utilisant les pages de 'man'.
 

Valid HTML 4.01 Transitional