C 读写mmap的参数无效?

C 读写mmap的参数无效?,c,linux,virtualbox,mmap,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

出于某种原因,我得到了
-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;
}
if((fd=open(argv[1],O_RDWR))<0)
{
fprintf(stderr,“无法打开%s:%s\n”,argv[1],strerror(errno));
返回1;
}
结构stat statbuf;
if(fstat(fd和statbuf))
{
fprintf(stderr,“统计文件:%s\n”,strerror(errno));
返回1;
}
char*fbase=mmap(NULL,statbuf.st_size,PROT_READ | PROT_WRITE,MAP_SHARED,fd,0);
如果(fbase==MAP_失败)
{
fprintf(标准,“mmap失败:%s\n”,strerror(errno));
返回1;
}

编辑:我应该补充,错误发生在
mmap
您的
statbuf中。st_size
0
。如果长度参数为
0
,则将失败

出现
EINVAL
错误
mmap()
的原因有三个:

  • 我们不喜欢
    addr
    length
    offset
    (例如,它们太大,或在页面边界上没有对齐)
  • (自Linux2.6.12以来)
    length
    为0
  • flags
    既不包含
    MAP\u PRIVATE
    也不包含
    MAP\u SHARED
    ,或者同时包含这两个值
事实证明,将
MAP\u SHARED
更改为
MAP\u PRIVATE
可以成功

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

如果您阅读了jxh对我的问题和他的回答的有用评论,您会发现这段代码对他有效,因为他可能试图
mmap
将主机文件系统文件映射到主机内存中

我观察到,从
MAP\u SHARED
切换到
MAP\u PRIVATE
也与此一致:因为私有映射内存对其他进程不可见,虚拟文件系统驱动程序可能不反对映射内存


解决方案是将我想要映射的文件移动到来宾的硬盘上,并从那里执行操作

你什么意思?这是我正在编写的代码片段。问题是“在哪里”您的代码片段的哪一行出现了EINVAL。对不起,我忘了指定。错误在mmap中。
st_size
的值是多少?我觉得自己像个白痴,但是:它是零,我替换了空文件,结果问题仍然存在。虽然以前长度是零,但我确保文件不是空的,问题仍然存在。这个问题真是一团糟,我会重新开始一个更详细的问题。我一定是疯了。我在一个干净的文件中尝试了它,它成功了,然后我尝试将完全相同的代码粘贴到它来自的文件中,但失败了。结果证明,设置
MAP\u PRIVATE
而不是
MAP\u SHARED
足以使它工作。这并不能解释任何事情,因为你说代码在一个干净的文件中工作。这就是为什么我喜欢stackoverflow。请不要认为从
MAP\u SHARED
切换到
MAP\u PRIVATE
是一个实际的解决方案。这甚至不是一个解决办法。使用
MAP\u SHARED
就地修改输出文件的程序在使用
MAP\u PRIVATE
时将自动失败。它看起来好像在工作,但可能不是。
void *mmap(void *addr, size_t length, int prot, int flags,
           int fd, off_t offset);