1.内存保护和文件访问模式交互
- mmap映射需要文件描述符的读权限(即open时需要加上读权限),不然不能使用。
- 所有内存保护组合与使用O_RDWR标记打开文件是兼容的。
- 一些硬件架构不允许对一个分页的只写访问。
prot值 | 描述 |
---|---|
PROT_NONE | 区域无法访问 |
PROT_READ | 区域内容可读取 |
PROT_WRITE | 区域内容可修改 |
PROT_EXEC | 区域内容可执行 |
flag值 | 描述 |
MAP_ANONYMOUS | 创建一个匿名映射 |
MAP_FIXED | 原样解释addr参数 |
MAP_LOCKED | 将映射分页锁进内存 |
MAP_HUGETLB | 创建一个使用巨页的映射 |
MAP_NORESERVE | 控制交换空间的预留,对映射数据的修改是私有的 |
MAP_POPULATE | 填充一个映射的分页 |
MAP_SHARED | 发生在映射数据上的变更对其他进程可见并会被反映到底层文件上 对文件的更新无法确保立即生效 |
MAP_UNINITIALIZED | 不清楚匿名映射 |
MAP_PRIVATE | 创建一个私有映射,区域中内容上所发生的变更对使用同一映射的其他进程不可见 对于文件映射来讲,所发生的变更将不会反应在底层文件上 |
对文件用只写打开测试结果(虚拟机ubuntu 18.04.1, cpu为Intel x86)
- 注:由于PROT_READ和PROT_EXEC保护要求被映射文件使用O_RDONLY或O_RDWR打开,就不测试了。
- PROT_WRITE保护要求被映射文件使用O_WRONLY或 O_RDWR打开,这里测试O_WRONLY是否可行。
对照试验:
总结:经过测试,在该版本下(虚拟机ubuntu 18.04.1, cpu为Intel x86)PROT_WRITE需要文件的读权限。此外,如果将文件权限改为O_RDONLY,其他不变,也打不开。因为PROT_WRITE要求文件有写权限。
2.标准中规定对offset和addr的对齐约束(SUSv4)
- 一个实现可能会要求offset为系统分页大小的倍数
- 如果指定了MAP_FIXED,那么一个实现可能会要求addr是分页对齐的。
- 如果指定了MAP_FIXED并且addr为非零值,那么addr和offset除以系统分页大小所得余数应该相等。
- mprotect(),msync(),munmap()中的addr参数也存在类似情况。
#include <func.h>
int main(int argc, char* argv[])
{
int fd = open("file", O_RDWR | O_CREAT, 0666);
if(-1 == fd){
perror("open");
return -1;
}
int length =4;
char* pMap = (char*)mmap(NULL, length, PROT_READ| PROT_WRITE, MAP_PRIVATE, fd, 4);
if(MAP_FAILED == pMap){
perror("mmap");
return -1;
}
if(munmap(pMap, length) == -1){
perror("munmap");
return -1;
}
return 0;
}
- 这里让offset取非零值mmap,不能通过。不过上面说的是addr与offset,这里是length和offset为4,并没有违背。
- 对于如何测试这个我不太懂,留个坑吧。