第二次使用ftruncate失败

3

我试图在shm_open和ftruncate成功后超出共享内存对象的限制。以下是代码:

char *uuid = GenerateUUID();
int fd = shm_open(uuid, O_RDWR|O_CREAT|O_EXCL, S_IRUSR|S_IWUSR);
if(fd == -1) perror("shm_open");

size_t shmSize = sizeof(container);
int ret = ftruncate(fd, shmSize);
perror("ftruncate first");

ret = ftruncate(fd, shmSize * 2);
perror("ftruncate second");

第一次ftruncate操作成功了,但第二次ftruncate操作失败了,错误代码是errno=22,“无效参数”。

我还尝试在mmap之后使用ftruncate来截取内存对象。根据ftruncate的手册页面,共享内存应该被格式化为零到新长度。

此外,我还尝试在子进程中截取内存对象(这是两个进程之间的IPC主题),但ftruncate返回“无效fd,没有这样的文件或目录”,但我能够在子进程中成功地shm_open和mmap。

有什么想法吗?谢谢!


仍然没有找到任何原因,我不得不做出临时解决方案:如果ftruncate失败,则关闭和shm_unlink对象,使用相同的名称创建一个新的文件描述符,对新对象进行ftruncate,通过。 - Itachi
2个回答

1
我认为这是shm_open()ftruncate()mmap()的已知“特性”。
第一次必须通过ftruncate()来给共享内存指定长度,但随后的ftruncate()会出现错误号22,你可以简单地忽略它。

1
它并没有真正解释观察到的行为。该链接与从另一个进程调用ftruncate()时出现的错误有关。 - Orest Hera
一个老问题,但我怀疑 ftruncate() 失败的原因是在更改文件大小之前必须 unmap 文件。例如,请参见 https://dev59.com/rGUo5IYBdhLWcg3w5Syl?noredirect=1&lq=1 - Bruce Adams

0

所使用的实现似乎符合旧版规范,其中当length超过先前长度时,返回错误是允许的行为:

如果文件以前比这个大小小,ftruncate()应该增加文件的大小或失败。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接