-
mmap program
Dear all,
When I read about the mmap function from a book I work out a example program.That program is for copy a content of a file to another file.In that they use lseek to set the offset of the destination file to the same size of the source file then they write a single bit on that file.When I remove this statements I got a Bus error.Any one can help me why we need to use lseek in that program.Whether it is need for memory mapping.
This is the program,
Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>
#ifndef MAP_FILE
#define MAP_FILE 0
#endif
int
main(int argc, char *argv[])
{
int fdin, fdout;
char *src, *dst;
struct stat statbuf;
if (argc != 3)
printf("usage: a.out <fromfile> <tofile>");
if ( (fdin = open(argv[1], O_RDONLY)) < 0)
printf("can't open %s for reading", argv[1]);
if ( (fdout = open(argv[2], O_RDWR | O_CREAT | O_TRUNC,0644)) < 0)
printf("can't creat %s for writing", argv[1]);
if (fstat(fdin, &statbuf) < 0)
printf("fstat error");
if (lseek(fdout, statbuf.st_size, SEEK_SET) == -1) /* Whey we need to use
this lseek followed by the
write on the destination
file*/
printf("lseek error");
if (write(fdout, "", 1) != 1)
printf("write error");
if ( (src = mmap(0, statbuf.st_size, PROT_READ,
MAP_FILE | MAP_SHARED, fdin, 0)) == (caddr_t) -1)
printf("mmap error for input");
if ( (dst = mmap(0, statbuf.st_size, PROT_WRITE,
MAP_FILE | MAP_SHARED, fdout, 0)) == (caddr_t) -1)
printf("mmap error for output");
memcpy(dst, src, statbuf.st_size);
exit(0);
}
Thanks.
-
Yes, mmap will not write beyond the end of an existing file (it will not EXTEND the mapped file itself), so you need to reserve the space in the file first by seeking to a suitable size, then writing to it. Since you apply O_TRUNC to the file when creating it, it will automatically have a zero size.
Note that there are a couple of drawbacks with using mmap to copy files:
1. It's quite likely slower than the corresponding plain read/write operations. The reason for this is that the mmap() interface uses the standard pagein/pageout mechanism to read/write pages. When reading in a "straight line" like you would to make a copy of a file, the filesystem can often cache parts of the file, and read/write operations on the file will be completed a bit quicker - it may not be a big difference, but it's likely to be better.
2. If you do not have enough virtual memory to map the entire file, you have to map multiple sections. I bet this program fails for a file that is bigger than about 3GB (unless the OS you are using is a 64-bit OS, in whcih case ginormous files will be possible to copy - but it doesn't change number 1 above).
--
Mats