La projection
Un exemple
Le programme suivant réalise une copie de fichier par projection d'un fichier
en mémoire. Il est intéressant de comparer les temps
d'exécutions entre la version avec projection et sans.
/*
* A fast copy utility
*
* Author: Jean-Baptiste Yunès
* Date : May 2000
*/
#if (_POSIX_C_SOURCE > 2)
#include <sys/mman.h>
#endif
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
int main(int argc,char *argv[]) {
int src, dst;
#if (_POSIX_C_SOURCE > 2)
void *src_addr;
#else
#define BUFLEN 1000
unsigned char buffer[1000];
ssize_t nc;
#endif
struct stat stat_buf;
if (argc!=3) {
fprintf(stderr,"Usage: %s <src> <dst>\n",argv[0]);
exit(EXIT_FAILURE);
}
if ( (src=open(argv[1],O_RDONLY)) < 0) {
fprintf(stderr,"%s: cannot open %s for reading\n",argv[0],argv[1]);
exit(EXIT_FAILURE);
}
if ( (dst=open(argv[2],O_CREAT|O_RDWR|O_TRUNC,S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) < 0 ) {
fprintf(stderr,"%s: cannot open %s for writing\n",argv[0],argv[2]);
close(src);
exit(EXIT_FAILURE);
}
#if (_POSIX_C_SOURCE > 2)
if ( fstat(src,&stat_buf) == -1 ) {
fprintf(stderr,"%s: cannot stat %s\n",argv[0],argv[1]);
close(dst);
close(src);
exit(EXIT_FAILURE);
}
if ( ftruncate(dst,stat_buf.st_size) < 0 ) {
fprintf(stderr,"%s: unable to write %ld bytes in %s\n",argv[0],
stat_buf.st_size,argv[2]);
close(dst);
close(src);
exit(EXIT_FAILURE);
}
/* Map the source file inside the address space */
src_addr = mmap(NULL,stat_buf.st_size,PROT_READ,MAP_NORESERVE|MAP_PRIVATE,src,0);
if ( src_addr==(void *)MAP_FAILED ) {
fprintf(stderr,"%s: problem mapping file %s\n",argv[0],argv[1]);
close(dst);
close(src);
exit(EXIT_FAILURE);
}
/* Write data to the destination file */
if ( write(dst,src_addr,stat_buf.st_size)!=stat_buf.st_size ) {
fprintf(stderr,"%s: problem writing %s\n",argv[0],argv[2]);
munmap(src_addr,stat_buf.st_size);
close(dst);
close(src);
exit(EXIT_FAILURE);
}
munmap(src_addr,stat_buf.st_size);
#else
do {
if ( (nc=read(src,buffer,BUFLEN)) < 0 ) {
fprintf(stderr,"%s: problem reading %s\n",argv[0],argv[1]);
close(dst);
close(src);
exit(EXIT_FAILURE);
}
if ( write(dst,buffer,nc)!= nc ) {
fprintf(stderr,"%s: problem writing %s\n",argv[0],argv[1]);
close(dst);
close(dst);
exit(EXIT_FAILURE);
}
} while ( nc );
#endif
close(dst);
close(src);
exit(EXIT_SUCCESS);
}