gpt4 book ai didi

我可以 mmap 长度大于文件大小的文件吗?

转载 作者:行者123 更新时间:2023-11-30 14:34:16 25 4
gpt4 key购买 nike

void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);

我不明白使用 MAP_PRIVATE 标志时 mmap 是如何工作的。我可以将大于文件 fd 大小的 length 传递给 mmap 吗?这样做之后,我可以写入和读取超出文件大小但在 length 以内的内存吗?

我正在编写一些计算文件 MD5 的代码。我决定编写仅将数据作为 void*size_t len 进行操作的函数,而不是使用标准库流函数。之前,我使用malloc并在使用它们之前将文件复制到一些malloc'ed内存中,但事实证明这对于大文件来说相当慢,而且一旦我发现mmap就非常愚蠢.

我正在处理的问题是,在计算任何数据的MD5之前,some padding and information is appended to the data that will be hashed.使用之前的 malloc 解决方案,我只需计算需要附加多少数据,然后 realloc 并写入。现在,我预先计算需要附加多少数据,并将增加的长度传递给 mmap。在小文件上,这工作正常,但在大文件上,尝试写入文件大小之外的地址会导致段错误。

这就是我想要做的:

#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#include <sys/mman.h>
#include <sys/stat.h>


// The Data + length struct
struct data{
void* s;
size_t len;
};

//mmap on opened file descriptor into a data struct
struct data* data_ffile(int fd)
{
struct data* ret = malloc(sizeof(struct data));

//Get the length of the file
struct stat desc;
fstat(fd, &desc);
ret->len = (size_t)desc.st_size;

//Calculate the length after appending
size_t new_len = ret->len + 1;
if((new_len % 64) > 56)
new_len += (64 * 2) - (new_len % 64);
else if((new_len % 64) <= 56)
new_len += 64 - (new_len % 64);

//Map the file with the increased length
ret->s = mmap(NULL, new_len, PROT_READ | PROT_WRITE,
MAP_PRIVATE, fd, 0);

if(ret->s == MAP_FAILED) exit(-1);

return ret;
}

//Append a character to the mmap'ed data
void data_addchar(struct data* w, unsigned char c)
{
((char*)w->s)[w->len++] = c;
return;
}

void md5_append(struct data* md)
{
data_addchar(md, 0x80);

while((md->len % 64) != 56){
data_addchar(md, (char)0);
}
}

int main(int argc, char** argv)
{
int fd = open(argv[1], O_RDONLY);
struct data* in = data_ffile(fd);
close(fd);

md5_append(in);
}

我对 mmap 有基本的误解吗?

最佳答案

Can I pass a length greater than the size of file fd to mmap? After doing so, can I write and read the memory that exceeds the size of the file but is within length?

这全部记录在 mmap POSIX specification 中:

The system shall always zero-fill any partial page at the end of an object. Further, the system shall never write out any modified portions of the last page of an object which are beyond its end. References within the address range starting at pa and continuing for len bytes to whole pages following the end of an object shall result in delivery of a SIGBUS signal.

  1. 是的,您可以 mmap 长度大于文件大小,并且
  2. 访问文件末尾以外的任何页面(最后一页(可能是部分页面)除外)将导致 SIGBUS

关于我可以 mmap 长度大于文件大小的文件吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59024621/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com