如何在分配空白页之前使用 mmap 映射文件?
How can I map a file with mmap while allocating an empty page before it?
所以我需要将一个文件映射到内存中,但同时在它的前面分配 space 来存储一些数据。
基本上我有这个:
int fd = open(path, O_RDONLY);
if (fd < 0) {
// error
}
struct stat file_info;
if (fstat(fd, &file_info) == -1) {
close(fd);
// error
}
int length = file_info.st_size;
int* data_pointer = mmap((void*) 0, length, PROT_READ, MAP_PRIVATE, fd, 0);
close(fd);
并且我希望在内存前面有 space,可能是一页之类的,我可以在其中执行此操作:
*data_pointer = length; // store length in space before file
// print out contents of file
const char* p = data_pointer + PAGE_SIZE;
for (int i = 0; i < *data_pointer; i++) {
printf("%c", p[i]);
}
printf("\n");
以便我以后可以这样做:
munmap(data_pointer, *data_pointer + PAGE_SIZE);
例如。我已经尝试用 malloc
分配我想要的 space 的数量,然后告诉 mmap
使用它的 addr
参数映射到那个 space,但是我不要认为这在 100% 的时间都有效,因为它更多的是提示而不是命令,而且我担心在某些平台上,mmap
实现可能会完全忽略 addr
参数.
你知道有什么更好的方法来完成我想要的而不必单独跟踪每个 mmap
调用的大小吗(我在动态加载的库之间共享这些指针,其中一些确实mmap
'ing,其中一些执行 munmap
'ing,必须处理所有这些是某种单独的列表是非常不优雅的)?
现在是深夜,我真的认为我在这里没有多大意义,但无论如何,我们将不胜感激任何帮助或见解。非常感谢您花时间阅读本文!
你走在正确的轨道上。您需要的缺失部分是 MAP_FIXED
:
int* data_pointer = mmap((void*) 0, length + PAGE_SIZE, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
if(data_pointer == MAP_FAILED) {
perror("mmap");
exit(1);
}
if(mmap(data_pointer + PAGE_SIZE, length, PROT_READ, MAP_PRIVATE|MAP_FIXED, fd, 0) == MAP_FAILED) {
perror("mmap");
exit(1);
}
您正确地指出,通常地址是 "more of a hint than an order",但传递 MAP_FIXED
使其成为订单。
如果您担心安全,man 2 mmap
说:
The only safe use for MAP_FIXED
is where the address range specified by addr
and length
was previously reserved using another mapping
这就是这个用途。
所以我需要将一个文件映射到内存中,但同时在它的前面分配 space 来存储一些数据。
基本上我有这个:
int fd = open(path, O_RDONLY);
if (fd < 0) {
// error
}
struct stat file_info;
if (fstat(fd, &file_info) == -1) {
close(fd);
// error
}
int length = file_info.st_size;
int* data_pointer = mmap((void*) 0, length, PROT_READ, MAP_PRIVATE, fd, 0);
close(fd);
并且我希望在内存前面有 space,可能是一页之类的,我可以在其中执行此操作:
*data_pointer = length; // store length in space before file
// print out contents of file
const char* p = data_pointer + PAGE_SIZE;
for (int i = 0; i < *data_pointer; i++) {
printf("%c", p[i]);
}
printf("\n");
以便我以后可以这样做:
munmap(data_pointer, *data_pointer + PAGE_SIZE);
例如。我已经尝试用 malloc
分配我想要的 space 的数量,然后告诉 mmap
使用它的 addr
参数映射到那个 space,但是我不要认为这在 100% 的时间都有效,因为它更多的是提示而不是命令,而且我担心在某些平台上,mmap
实现可能会完全忽略 addr
参数.
你知道有什么更好的方法来完成我想要的而不必单独跟踪每个 mmap
调用的大小吗(我在动态加载的库之间共享这些指针,其中一些确实mmap
'ing,其中一些执行 munmap
'ing,必须处理所有这些是某种单独的列表是非常不优雅的)?
现在是深夜,我真的认为我在这里没有多大意义,但无论如何,我们将不胜感激任何帮助或见解。非常感谢您花时间阅读本文!
你走在正确的轨道上。您需要的缺失部分是 MAP_FIXED
:
int* data_pointer = mmap((void*) 0, length + PAGE_SIZE, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
if(data_pointer == MAP_FAILED) {
perror("mmap");
exit(1);
}
if(mmap(data_pointer + PAGE_SIZE, length, PROT_READ, MAP_PRIVATE|MAP_FIXED, fd, 0) == MAP_FAILED) {
perror("mmap");
exit(1);
}
您正确地指出,通常地址是 "more of a hint than an order",但传递 MAP_FIXED
使其成为订单。
如果您担心安全,man 2 mmap
说:
The only safe use for
MAP_FIXED
is where the address range specified byaddr
andlength
was previously reserved using another mapping
这就是这个用途。