La fonction mmap permet la projection de fichiers en mémoire. Le segment du fichier indiqué est placé en mémoire à partir de l'adresse indiquée. Le segment de fichier peut ainsi être parcouru par des accès par adresse sans utiliser de commande de lecture ou d'écriture.
#include <sys/mman.h>
#include <sys/types.h>
void *mmap(void *adr, int len,
int prot, int options,
int desc, int offset);
int munmap(void *adr, int len);
L'adresse adr indique où doit être placé le fichier, cette adresse doit être une adresse de début de page (un multiple de sysconf(_SC_PAGE_SIZE)), si le paramètre est NULL alors le système sélectionne l'adresse de placement qui est retournée par la fonction. L'intervalle de position
du fichier desc est placé en mémoire.
prot indique les protections d'accès sous HP-UX les protections suivantes sont disponible:
--- PROT_NONE
r-- PROT_READ
r-x PROT_READ|PROT_EXECUTE
rw PROT_READ|PROT_WRITE
rwx PROT_READ|PROT_WRITE|PROT_EXECUTE
options indique si l'on veut que les écritures réalisées dans les pages contenant la projection soient partagées (MAP_SHARED), ou au contraire qu'une copie sur écriture soit réalisée (MAP_PRIVATE).
La fonction munmap permet de libérer la zone mémoire d'adresse adr et de longueur len.
Pour une autre forme de mémoire partagée, voir le chapitre 15 sur les IPC.
Un exemple d'utilisation de mmap pour copier un fichier:
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <fcntl.h>
int main(int argçhar *argv[])
{
int fdin,fdout;
struct stat statbuf;
char *srçdst;
if (argc != 3)
{
fprintf(stderr,"usage: %s source destination ",argv[0]);
exit(-1);
}
if ((fdin = open(argv[1], O_RDONLY)) < 0)
{
fprintf(stderr,"impossible d'ouvrir: %s en lecture ",argv[1]);
exit(-2);
}
if ((fdout = open(argv[2], O_RDWR|O_CREAT|O_TRUNC,0666)) < 0)
{
fprintf(stderr,"impossible d'ouvrir: %s en ecriture ",argv[2]);
exit(-3);
}
if (fstat(fdin,&statbuf) < 0 )
{
fprintf(stderr,"impossible de faire stat sur %s ",argv[1]);
exit(-4);
}
if (lseek(fdout, statbuf.st_size -1 , SEEK_SET) == -1 )
{
fprintf(stderr,"impossible de lseek %s ",argv[2]);
exit(-5);
}
if (write(fdout,"",1) != 1)
{
fprintf(stderr,"impossible d'ecrire sur %s ",argv[2]);
exit(-6);
}
if ((src = mmap (0,statbuf.st_size, PROT_READ,
MAP_FILE | MAP_SHARED, fdin,0)) == (caddr_t) -1 )
{
fprintf(stderr,"impossible de mapper %s ",argv[1]);
exit(-7);
}
if ((dst = mmap (0,statbuf.st_size, PROT_READ | PROT_WRITE,
MAP_FILE | MAP_SHARED, fdout,0)) == (caddr_t) -1 )
{
fprintf(stderr,"impossible de mapper %s ",argv[2]);
exit(-8);
}
memcpy(dst,srçtatbuf.st_size); /* copie */
exit(0);
}
Programme très rapide, il pourrait être encore amélioré si la fonction
madvice fonctionnait.
Attention, quand vous utilisez mmap les adresses mémoire dans la zone mappée ne sont pas nécessairement bien alignées.
Next: Tubes et Tubes Nommés Up: La mémoire virtuelle Previous: L'appel fork et la
Dominique REVUZ