C语言 如何确定使用mmap()时所有Map的页面是否有效?

pftdvrlh  于 2023-06-21  发布在  其他
关注(0)|答案(1)|浏览(71)

我了解到mmap()分配的页面可能无法使用,即使调用返回成功。例如if a file is being mapped and the len passed to mmap() is sufficiently larger than the file。在这种情况下,超出文件所用页面的任何页面,即使在请求的大小内,如果试图使用它们,也会产生SIGBUS
是否有任何方法可以直接确定从Map开始到len所有字节是否可以安全访问?除了手动测量文件的长度,或设置SIGBUS处理程序,或以其他方式(彻底)检查是否满足页面不可访问的任何原因之外,我还可以这样做吗?

// Assuming PAGE_SIZE == 4096
int fd = open("file", O_RDONLY);
void *buffer = mmap(NULL, 8192, PROT_READ, MAP_SHARED, fd, 0);
// Is there any way to determine if reading bytes 4093-8192 will cause a bus error?
// Besides measuring if the size of the file is greater than 4092?

而不是检查文件大小,以确定是否有任何页面 * 将 * 不可用 *,因为文件太小 *,我可以 * 直接 * 确定是否有任何页面 * 不可用 * 任何原因 *?

eivgtgni

eivgtgni1#

规范的方法是使用fstat()来测量文件的大小,如果文件太小则失败。没有更多的 '直接' 方式来查询页面的可用性,也不需要一个,因为manpage显示,在 * 信号 * 下,SIGBUS发生的唯一方式是如果文件太小:

SIGBUS Attempted access to a page of the buffer that lies beyond
      the end of the mapped file.  For an explanation of the
      treatment of the bytes in the page that corresponds to the
      end of a mapped file that is not a multiple of the page
      size, see NOTES.

下面的代码是如何安全使用mmap()的示例:

#define PAGE_ALIGN(S) ((S)+PAGE_SIZE-1&~(PAGE_SIZE-1))
#define EXPECTED_SIZE /* ... */

int fd = open("file", O_RDONLY);
struct stat statbuf;
if (fstat(fd, &statbuf) || PAGE_ALIGN(statbuf.st_size) < EXPECTED_SIZE)
    return EXIT_FAILURE;
void *mapping = mmap(NULL, EXPECTED_SIZE, PROT_READ, MAP_SHARED, fd, 0);
if (mapping == MAP_FAILED)
    return EXIT_FAILURE;

相关问题