File Mapping
/* * This copies files by memory mapping them. This is to demonstrate memory * mapping, rather than because this it's a wonderful way to do this. */ #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <sys/mman.h> #include <fcntl.h> #include <unistd.h> #include <string.h> #include <errno.h> #define BUF_SIZE 1024 /* Error and die. */ void croak(char *msg, int syserr) { fprintf(stderr, "%s", msg); if(syserr) fprintf(stderr, ": %s", strerror(errno)); fprintf(stderr, "\n"); exit(1); } int main(int argc, char **argv) { int infile, outfile; /* Input and output file descrs. */ int flen, m; /* File length. */ char *inloc, *outloc; /* Mapped locations. */ char *inscan, *outscan; /* Memory scanning pointers. */ if(argc != 3) croak("Need three args.", 0); /* Open the input file to read. */ infile = open(argv[1], O_RDONLY); if(infile < 0) croak("Input file open", 1); /* Find the lenth of the file by seeking to the end. */ flen = lseek(infile, 0, SEEK_END); if(flen < 0) croak("Input seek to end", 1); /* Open output file, writable, truncate existing content, or create if not. */ outfile = open(argv[2], O_RDWR | O_CREAT, 0777); if(outfile < 0) croak("Output file open", 1); /* Set the size of the output file to the size of the input file. If it's larger, the extra will be removed. If smaller, it's filled with zero bytes. */ if(ftruncate(outfile, flen) < 0) croak("Output size set", 1); /* Map the files into virtual memory. */ inloc = mmap(NULL, flen, PROT_READ, MAP_SHARED, infile, 0); if(outloc == (void *) -1) croak("Input map", 1); outloc = mmap(NULL, flen, PROT_WRITE, MAP_SHARED, outfile, 0); if(outloc == (void *) -1) croak("Output map", 1); /* Copy the file by copying the memory regions. */ inscan = inloc; outscan = outloc; for(m = flen; m--;) *outscan++ = *inscan++; /* Clean up this mess. */ munmap(inloc, flen); munmap(outloc, flen); close(infile); close(outfile); }