#define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include int main(int argc, char *argv[]) { int err; if (argc != 3) { fprintf(stderr, "usage: %s from_file to_file", argv[0]); exit(0); } /* from */ int from = open(argv[1], O_RDONLY, 0644); assert(from >= 0); struct stat st_buf; assert(fstat(from, &st_buf) >= 0); size_t size = st_buf.st_size; void *from_mmap = mmap(NULL, size, PROT_READ, MAP_SHARED, from, 0); assert(from_mmap >= 0); #if USE_MADVISE err = madvise(from_mmap, size, MADV_SEQUENTIAL); assert(err >= 0); #endif /* to */ int to = open(argv[2], O_CREAT|O_RDWR, st_buf.st_mode); assert(to >= 0); int i = 0; assert(lseek(to, size - sizeof(int), 0L) >= 0); assert(write(to, (&i), sizeof(int)) == sizeof(int)); errno=0; void *to_mmap = mmap(NULL, size, PROT_WRITE, MAP_SHARED, to, 0); assert_perror(errno); #if USE_MADVISE errno=0; err = madvise(to_mmap, size, MADV_SEQUENTIAL); assert_perror(errno); #endif /* copy */ memcpy(to_mmap, from_mmap, size); #if WITH_MSYNC assert(msync(to_mmap, size, MS_SYNC) >= 0); #endif #if WITH_MUNMAP assert(munmap(to_mmap, size) >= 0); #endif assert(ftruncate(to, size) >= 0); return 0; }