#include <sys/mman.h> /* 成功返回映射区起始地址,出错返回MAP_FAILED */ void *mmap(void *addr, size_t len, int prot, int flag, int filedes, off_t off);
#include <stdio.h> #include <fcntl.h> #include <sys/mman.h> #include <string.h> #define FILE_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) int main(int argc, char *argv[]) { int fdin, fdout; void *src, *dst; struct stat statbuf; if (argc != 3) { printf("usage: %s <fromfile> <tofile>\n", argv[0]); return -1; } fdin = open(argv[1], O_RDONLY); fdout = open(argv[2], O_RDWR | O_CREAT | O_TRUNC, FILE_MODE); fstat(fdin, &statbuf); lseek(fdout, statbuf.st_size - 1, SEEK_SET); write(fdout, " ", 1); /* lseek偏移量大于文件长度时。写操作将加长文件 */ src = mmap(0, statbuf.st_size, PROT_READ, MAP_SHARED, fdin, 0); dst = mmap(0, statbuf.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fdout, 0); memcpy(dst, src, statbuf.st_size); /* 数据复制 */ munmap(src, statbuf.st_size); munmap(dst, statbuf.st_size); return 0; }
lseek + write的组合操作使得目标文件的大小添加到和源文件大小同样。由于当lseek设置的文件偏移量大于文件当前长度时。下一个写操作将会使文件增大。假设没有对目标文件扩大。那么进程会接收到SIGBUS信号。表示存储区中有地址无法映射到文件里。
原文:http://www.cnblogs.com/yxwkf/p/5093182.html