Provided by:
manpages-fr-dev_3.27fr1.4-1_all 
NOM
mmap, munmap - Etablir/supprimer une projection en memoire (map/unmap)
des fichiers ou des peripheriques
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);
DESCRIPTION
mmap() cree une nouvelle projection dans l'espace d'adressage virtuel
du processus appelant. L'adresse de demarrage de la nouvelle projection
est indiquee dans addr. Le parametre length indique la longueur de la
projection.
Si addr est NULL, le noyau choisit l'adresse a laquelle demarrer la
projection ; c'est la methode la plus portable pour creer une nouvelle
projection. Si addr n'est pas NULL, le noyau le considere comme une
indication sur l'endroit ou placer la projection ; sous Linux, elle
sera placee a une frontiere de page proche. L'adresse de la nouvelle
projection est renvoyee comme resultat de l'appel.
Le contenu d'une projection de fichier (par opposition a une projection
anonyme ; voir ci-dessous MAP_ANONYMOUS) est initialise avec length
octets a partir de la position offset dans le fichier (ou autre objet)
correspondant au descripteur de fichier fd. offset doit etre un
multiple de la taille de page, renvoyee par sysconf(_SC_PAGE_SIZE).
L'argument prot indique la protection que l'on desire pour cette zone
de memoire, 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 memoire est
inaccessible) soit d'un OU binaire entre les constantes suivantes :
PROT_EXEC On peut executer du code dans la zone memoire.
PROT_READ On peut lire le contenu de la zone memoire.
PROT_WRITE On peut ecrire dans la zone memoire.
PROT_NONE Les pages ne peuvent pas etre accedees.
Le parametre flags determine si les modifications de la projection sont
visibles depuis les autres processus projetant la meme region, et si
les modifications sont appliquees au fichier sous-jacent. Ce
comportement est determine 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 ce
fichier, et sont appliquees au fichier sous-jacent. En
revanche, ce dernier n'est pas necessairement mis a jour
tant qu'on n'a pas appele msync(2) ou munmap().
MAP_PRIVATE
Creer une projection privee, utilisant la methode de copie a
l'ecriture. Les modifications de la projection ne sont pas
visibles depuis les autres processus projetant le meme
fichier, et ne modifient pas le fichier lui-meme. Il n'est
pas precise si les changements effectues dans le fichier
apres l'appel mmap() seront visibles.
Ces deux attributs sont decrits dans POSIX.1-2001.
De plus, zero ou plus des valeurs suivantes peuvent etre 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 ete
ajoute pour permettre a la pile d'un thread d'etre allouee dans
les deux premiers gigaoctets de memoire, afin d'ameliorer les
performances des changements de contexte sur les premiers
processeurs 64 bits. Les processeurs x86-64 modernes n'ont plus
ces problemes de performance, donc l'utilisation de cet attribut
n'est pas necessaire sur ces systemes. L'attribut MAP_32BIT est
ignore quand MAP_FIXED est positionne.
MAP_ANON
Synonyme de MAP_ANONYMOUS. Deconseille.
MAP_ANONYMOUS
La projection n'est supportee par aucun fichier ; son contenu
est initialise a 0. Les arguments fd et offset sont ignores ;
cependant, certaines implementations demandent que fd soit -1 si
MAP_ANONYMOUS (ou MAP_ANON) est utilise, et les applications
portables doivent donc s'en assurer. Cet attribut, utilise en
conjonction de MAP_SHARED, n'est implemente que depuis Linux
2.4.
MAP_DENYWRITE
Cet attribut est ignore. (Autrefois, une tentative d'ecriture
dans le fichier sous-jacent echouait avec l'erreur ETXTBUSY.
Mais ceci permettait des attaques par deni de service.)
MAP_EXECUTABLE
Cet attribut est ignore.
MAP_FILE
Attribut pour compatibilite. Ignore.
MAP_FIXED
Ne pas considerer addr comme une indication : n'utiliser que
l'adresse indiquee. addr doit etre un multiple de la taille de
page. Si la zone memoire indiquee par addr et len recouvre des
pages d'une projection existante, la partie recouverte de la
projection existante sera ignoree. Si l'adresse indiquee ne peut
etre utilisee, mmap() echouera. Il est deconseille d'utiliser
cette option, car requerir une adresse fixe pour une projection
n'est pas portable.
MAP_GROWSDOWN
Utilise pour les piles. Indique au systeme de gestion de la
memoire virtuelle que la projection doit s'etendre en croissant
vers le bas de la memoire.
MAP_HUGETLB (depuis Linux 2.6.32)
Allouer la projection a l'aide << d'enormes pages >>. Consultez
le fichier source du noyau Documentation/vm/hugetlbpage.txt pour
plus d'informations.
MAP_LOCKED (depuis Linux 2.5.37)
Verrouille la page projetee en memoire a la maniere de mlock(2).
Cet attribut est ignore sur les noyaux plus anciens.
MAP_NONBLOCK (depuis Linux 2.5.46)
N'a de sens qu'en conjonction avec MAP_POPULATE. Ne pas
effectuer de lecture anticipee : creer seulement les entrees de
tables de page pour les pages deja presentes 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 etre implementee de nouveau.
MAP_NORESERVE
Ne pas reserver d'espace de swap pour les pages de cette
projection. Une telle reservation garantit que l'on puisse
modifier les zones soumises a une copie-en-ecriture. Sans
reservation, on peut recevoir un signal SIGSEGV durant une
ecriture, s'il n'y a plus de place disponible. Consultez
egalement la description du fichier
/proc/sys/vm/overcommit_memory dans la page proc(5). Dans les
noyaux anterieurs a 2.6, cet attribut n'avait d'effet que pour
les projections privees modifiables.
MAP_POPULATE (depuis Linux 2.5.46)
Remplit les tables de pages pour une projection. Pour une
projection de fichier, ceci s'effectue par une lecture anticipee
du fichier. Les acces ulterieurs a la projection ne seront pas
bloques par des fautes de pages. MAP_POPULATE n'est gere pour
les projections privees que depuis Linux 2.6.23.
MAP_STACK (depuis Linux 2.6.27)
Alloue la projection a une adresse qui convient pour la pile
d'un processus ou d'un thread. Cet attribut n'a pour l'instant
aucun effet, mais est utilise par l'implementation des threads
de la glibc de telle sorte que si certaines architectures
necessitent un traitement particulier pour l'allocation de la
pile, leur prise en charge par la suite par la glibc pourra etre
implementee de facon transparente.
MAP_UNINITIALIZED (depuis Linux 2.6.33)
N'efface pas les pages anonymes. Cet attribut n'a pour l'instant
un effet que si le noyau a ete configure avec l'option
CONFIG_MMAP_ALLOW_UNINITIALIZED. A cause des implications sur la
securite, cette option n'est normalement active que sur des
peripheriques embarques (c'est-a-dire avec des peripheriques
avec lesquels il est possible d'avoir un controle total de la
memoire utilisateur).
Parmi les attributs ci-dessus, seul MAP_FIXED est specifie dans
POSIX.1-2001. Cependant, la plupart des systemes gerent aussi
MAP_ANONYMOUS (ou son synonyme MAP_ANON).
Certains systemes utilisent les attributs supplementaires MAP_AUTOGROW,
MAP_AUTORESRV, MAP_COPY et MAP_LOCAL.
La memoire obtenue par mmap est preservee au travers d'un fork(2), avec
les memes 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 memoire restante est remplie de zeros lors de la projection, et les
ecritures 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 ajoutees ou supprimees ne sont pas precises.
munmap()
L'appel systeme munmap() detruit la projection dans la zone de memoire
specifiee, et s'arrange pour que toute reference ulterieure a cette
zone memoire declenche une erreur d'adressage. La projection est aussi
automatiquement detruite lorsque le processus se termine. A l'inverse,
la fermeture du descripteur de fichier ne supprime pas la projection.
L'adresse addr doit etre un multiple de la taille de page. Toutes les
pages contenant une partie de l'intervalle indique sont liberees, et
tout acces ulterieur declenchera SIGSEGV. Aucune erreur n'est detectee
si l'intervalle indique ne contient pas de page projetee.
Modifications d'horodatage pour les projections support'ees par un fichier
Pour les projections supportees par un fichier, le champ st_atime du
fichier peut etre mis a jour a tout moment entre l'appel mmap() et le
munmap() correspondant. Le premier acces dans la page projetee mettra
le champ a jour si cela n'a pas ete deja fait.
Les champs st_ctime et st_mtime pour un fichier projete avec PROT_WRITE
et MAP_SHARED seront mis a jour apres une ecriture dans la region
projetee, et avant l'eventuel msync(2) suivant avec attribut MS_SYNC ou
MS_ASYNC.
VALEUR RENVOY'EE
mmap() renvoie un pointeur sur la zone de memoire, s'il reussit. En cas
d'echec il retourne la valeur MAP_FAILED (c.-a-d. (void *) -1) et errno
contient le code d'erreur. munmap() renvoie 0 s'il reussit. En cas
d'echec, -1 est renvoye et errno contient le code d'erreur
(probablement EINVAL).
ERREURS
EACCES Le descripteur ne correspond pas a un fichier normal, ou on
demande une projection privee MAP_PRIVATE mais fd n'est pas
ouvert en lecture, ou on demande une projection partagee
MAP_SHARED avec protection PROT_WRITE, mais fd n'est pas ouvert
en lecture et ecriture (O_RDWR). Ou encore PROT_WRITE est
demande, mais le fichier est ouvert en ajout seulement.
EAGAIN Le fichier est verrouille, ou trop de pages ont ete verrouillees
en memoire (consultez setrlimit(2)).
EBADF fd n'est pas un descripteur de fichier valable (et MAP_ANONYMOUS
n'etait pas precise).
EINVAL addr ou length ou offset sont invalides (par exemple : zone trop
grande, ou non alignee sur une frontiere de page).
EINVAL (depuis Linux 2.6.12) length est nul.
EINVAL flags ne contient ni MAP_PRIVATE ni MAP_SHARED, ou les contient
tous les deux.
ENFILE La limite du nombre total de fichiers ouverts sur le systeme a
ete atteinte.
ENODEV Le systeme de fichiers sous-jacent ne supporte pas la projection
en memoire.
ENOMEM Pas assez de memoire, ou le nombre maximal de projections par
processus a ete depasse.
EPERM L'argument prot a demande PROT_EXEC mais la zone appartient a un
fichier sur un systeme de fichiers monte sans permission
d'execution.
ETXTBSY
MAP_DENYWRITE a ete reclame mais fd est ouvert en ecriture.
L'acces a une zone de projection peut declencher les signaux suivants :
SIGSEGV
Tentative d'ecriture dans une zone en lecture seule.
SIGBUS Tentative d'acces a une portion de la zone qui ne correspond pas
au fichier (par exemple apres la fin du fichier, y compris
lorsqu'un autre processus l'a tronque).
CONFORMIT'E
SVr4, BSD 4.4, POSIX.1-2001.
DISPONIBILIT'E
Sur les systemes POSIX sur lesquels mmap(), msync(2) et munmap() sont
disponibles, la constante symbolique _POSIX_MAPPED_FILES est definie
dans <unistd.h> comme etant une valeur superieure a 0. (Consultez aussi
sysconf(3).)
NOTES
Depuis le noyau 2.4, cet appel systeme a ete remplace par mmap2(2). De
nos jours, la fonction mmap() de la glibc appelle mmap2(2) avec la
bonne valeur pour offset.
Sur certaines architectures materielles (par exemple, i386), PROT_WRITE
implique PROT_READ. Cela depend de l'architecture si PROT_READ implique
PROT_EXEC ou non. Les programmes portables doivent toujours indiquer
PROT_EXEC s'ils veulent executer du code dans la projection.
La maniere portable de creer une projection est de specifier addr a 0
(NULL), et d'omettre MAP_FIXED dans flags. Dans ce cas, le systeme
choisit l'adresse de la projection ; l'adresse est choisie de maniere a
ne pas entrer en conflit avec une projection existante et de ne pas
etre nulle. Si l'attribut MAP_FIXED est indique et si addr vaut 0
(NULL), l'adresse projetee sera zero (NULL).
BOGUES
Sous Linux, il n'y a aucune garantie comme celles indiquees plus haut a
propos de MAP_NORESERVE. Par defaut, n'importe quel processus peut etre
tue a tout moment lorsque le systeme n'a plus de memoire.
Dans les noyaux anterieurs a 2.6.7, le drapeau MAP_POPULATE n'avait
d'effet que si prot etait PROT_NONE.
SUSv3 indique que mmap() devrait echouer si length est 0. Cependant,
avec les versions de Linux anterieures a 2.6.12, mmap() reussissait
dans ce cas : aucune projection n'etait creee, et l'appel renvoyait
addr. Depuis le noyau 2.6.12, mmap() echoue avec le code d'erreur
EINVAL si length est nul.
EXEMPLE
Le programme suivant affiche la partie du fichier, precise par le
premier argument de la ligne de commande, sur la sortie standard. Les
octets qui seront affiches sont precises a partir d'un offset
(deplacement) et d'une longueur en deuxieme et troisieme parametre. Le
code fait une projection memoire des pages necessaires du fichier puis
utilise write(2) pour afficher les octets voulus.
#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);
/* l'offset pour mmap() doit etre aligne sur une page */
if (offset >= sb.st_size) {
fprintf(stderr, "L'offset depasse 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 parametre longueur
==> affichage jusqu'a 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, "ecriture partielle");
exit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS);
} /* main */
VOIR AUSSI
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),
shm_overview(7)
B.O. Gallmeister, POSIX.4, O'Reilly, pp. 128-129 et 389-391.
COLOPHON
Cette page fait partie de la publication 3.27 du projet man-pages
Linux. Une description du projet et des instructions pour signaler des
anomalies peuvent etre trouvees a l'adresse
<URL:http://www.kernel.org/doc/man-pages/>.
TRADUCTION
Depuis 2010, cette traduction est maintenue a l'aide de l'outil po4a
<URL:http://po4a.alioth.debian.org/> par l'equipe de traduction
francophone au sein du projet perkamon
<URL:http://perkamon.alioth.debian.org/>.
Thierry Vignaud (2002), Alain Portal
<URL:http://manpagesfr.free.fr/> (2006). Julien Cristau et l'equipe
francophone de traduction de Debian (2006-2009).
Veuillez signaler toute erreur de traduction en ecrivant a
<debian-l10n-french@lists.debian.org> ou par un rapport de bogue sur le
paquet manpages-fr.
Vous pouvez toujours avoir acces a la version anglaise de ce document
en utilisant la commande << man -L C <section> <page_de_man> >>.