Next: Tubes et Tubes Nommés Up: La mémoire virtuelle Previous: L'appel fork et la

Projection de fichiers en mémoire

 

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 dtex2html_wrap_inline5913'ouvrir: %s en lecture ",argv[1]);
exit(-2);
}
if ((fdout = open(argv[2], O_RDWR|O_CREAT|O_TRUNC,0666)) < 0)
{
fprintf(stderr,"impossible dtex2html_wrap_inline5913'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 dtex2html_wrap_inline5913'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
Mon Feb 2 12:10:31 MET 1998
Une Bug Un mail Merci