我出于某种原因得到了-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
。
答案 0 :(得分:55)
结果将 MAP_SHARED
更改为MAP_PRIVATE
可以使此成功。
这个失败的原因很微妙:我的代码在VirtualBox VM中运行,我试图mmap
的文件位于我的主机上的共享目录中。 VirtualBox虚拟文件系统显然没有跨管理程序的边界使用mmap
选项实现MAP_SHARED
。
如果您将阅读jxh对我的问题和答案的有用评论,事实证明此代码对他有用,因为他可能试图将mmap
主机文件系统文件放入主机内存中。
我观察到从MAP_SHARED
切换到MAP_PRIVATE
也与此一致:由于私有映射的内存对其他进程是不可见的,因此虚拟文件系统驱动程序可能不会反对映射内存。 / p>
解决方案是将我想要映射的文件移动到访客的硬盘驱动器并从那里执行操作。
答案 1 :(得分:15)
您的statbuf.st_size
是0
。如果 length 参数为0
,则mmap()
将失败。
EINVAL
错误mmap()
列出了3个原因:
void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);
...
- 我们不喜欢
addr
,length
或offset
(例如,它们太大,或者未在页面边界上对齐)。- (自Linux 2.6.12起)
length
为0。flags
不包含MAP_PRIVATE
或MAP_SHARED
,或包含这两个值。