读写mmap的参数无效?

时间:2013-08-24 16:05:17

标签: 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;
}

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

2 个答案:

答案 0 :(得分:55)

结果将MAP_SHARED更改为MAP_PRIVATE可以使此成功。

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

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

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

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

答案 1 :(得分:15)

您的statbuf.st_size0。如果 length 参数为0,则mmap()将失败。

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

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

...

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