读写mmap的参数无效?

Ale*_*lex 20 c linux virtualbox mmap

-EINVAL出于某种原因,我不明白为什么.这是我打开并尝试mmap该文件的位置:

if ((fd = open(argv[1], O_RDWR)) < 0)
{
    fprintf(stderr, "Failed to open %s: %s\n", argv[1], strerror(errno));
    return 1;
}

struct stat statbuf;
if (fstat(fd, &statbuf))
{
    fprintf(stderr, "stat filed: %s\n", strerror(errno));
    return 1;
}

char* fbase = mmap(NULL, statbuf.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (fbase == MAP_FAILED)
{
    fprintf(stderr, "mmap failed: %s\n", strerror(errno));
    return 1;
}
Run Code Online (Sandbox Code Playgroud)

编辑:我应该补充,错误发生在mmap.

Ale*_*lex 55

结果改变了MAP_SHAREDMAP_PRIVATE允许这成功.

这个失败的原因很微妙:我的代码在VirtualBox VM中运行,我尝试的文件mmap位于主机上的共享目录中.VirtualBox虚拟文件系统显然没有通过跨管理程序边界mmapMAP_SHARED选项实现.

如果您将阅读jxh对我的问题和答案的有用评论,事实证明这个代码对他有效,因为他可能正在尝试将mmap主机文件系统文件放入主机内存中.

我从切换MAP_SHARED到的观察MAP_PRIVATE也与此一致:由于私有映射的内存对其他进程是不可见的,因此虚拟文件系统驱动程序可能不会反对映射内存.

解决方案是将我想要映射的文件移动到访客的硬盘驱动器并从那里执行操作.

  • 这就是我喜欢stackoverflow的原因. (3认同)

jxh*_*jxh 15

statbuf.st_size0.mmap()如果length参数是,则会失败0.

列出的EINVAL错误有3个原因mmap():

void *mmap(void *addr, size_t length, int prot, int flags,
           int fd, off_t offset);
Run Code Online (Sandbox Code Playgroud)

...

  • 我们不喜欢addr,, lengthoffset(例如,它们太大,或者没有在页面边界上对齐).
  • (自Linux 2.6.12起)length为0.
  • flags既不含有MAP_PRIVATEMAP_SHARED,或包含这两个值.