我有一个简单的程序:
int main(void) {
int fd;
const char *text = "This is a test";
fd = open("/tmp/msyncTest", (O_CREAT | O_TRUNC | O_RDWR), (S_IRWXU | S_IRWXG | S_IRWXO) );
if ( fd < 0 ) {
perror("open() error");
return fd;
}
/* mmap the file. */
void *address;
off_t my_offset = 0;
address = mmap(NULL, 4096, PROT_WRITE, MAP_SHARED, fd, my_offset);
if ( address == MAP_FAILED ) {
perror("mmap error. " );
return -1;
}
/* Move some data into the file using memory map. */
strcpy( (char *)address, text);
/* use msync to write changes to disk. */
if ( msync( address, 4096 , MS_SYNC ) < 0 ) {
perror("msync failed with error:");
return -1;
}
else {
printf("%s","msync completed successfully.");
}
close(fd);
unlink("/tmp/msyncTest");
}
我的代码有什么问题吗?我做了一些简单的测试,看来问题来自于strcpy
。但根据定义,我认为没有问题。
If
fd = open("/tmp/msyncTest", (O_CREAT | O_TRUNC | O_RDWR), (S_IRWXU | S_IRWXG | S_IRWXO) );
成功了,fd
将引用零长度文件(O_TRUNC
)。致电给mmap()
address = mmap(NULL, 4096, PROT_WRITE, MAP_SHARED, fd, my_offset);
建立内存映射,但页面不对应于对象。
http://pubs.opengroup.org/onlinepubs/7908799/xsh/mmap.html http://pubs.opengroup.org/onlinepubs/7908799/xsh/mmap.html对于这种情况,有以下说法:
系统始终对对象末尾的任何部分页面进行零填充。此外,系统绝不会写出对象最后一页超出其末尾的任何修改部分。从 pa 开始并持续 len 字节到对象末尾之后的整个页的地址范围内的引用会导致 SIGBUS 信号的传送。
相似地,man mmap
关于 Linux 笔记
使用映射区域可能会产生以下信号:
[...]
SIGBUS尝试访问缓冲区中与文件不对应的部分(例如,超出文件末尾,包括另一个进程截断了文件的情况)。
因此,您必须ftruncate()
文件长度非零before mmap()
ing它(除非你是mmap()
ing 匿名内存)。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)