3

I'm trying to exceed the shared memory object after shm_open and ftruncate successfully at fisrt. Here is the code,

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");

It could pass the first ftruncate, but for the second ftruncate, it exceeds failed with errno=22, "Invalid argument".

I also tried to ftruncate the memory object after mmap, refer to the ftruncate's man page, the shared memory should be formatted as zero to the new length.

Besides, I also tried to ftruncate the memory object in the child process (This is an IPC topic among two processes), the ftruncate returns "Invalid fd, no such file or directory" but I could shm_open and mmap successfully in child process.

Any ideas? Thanks!

Itachi
  • 5,777
  • 2
  • 37
  • 69
  • Still didn't find out any reasons, I had to make a temporary solution: if ftruncate failed, close and shm_unlink the object, create a new file descriptor using the same name, ftruncate the new object, passed. – Itachi Dec 05 '13 at 08:08

2 Answers2

1

I think this is a known "feature" of shm_open(), ftruncate(), mmap().

You have to ftruncate() the first time through to give the shared memory a length, but subsequent times ftruncate() gives that error number 22, which you can simply ignore.

Stephen Kennedy
  • 20,585
  • 22
  • 95
  • 108
rob shaw
  • 11
  • 1
  • 1
    It does not really explains observed behavior. The link is related to errors with `ftruncate()` called from another process. – Orest Hera Sep 25 '15 at 10:54
  • An old question but I suspect the reason `ftruncate()` fails is that you have to `unmap` a file before you change its size. See for example https://stackoverflow.com/questions/15684771/how-to-portably-extend-a-file-accessed-using-mmap?noredirect=1&lq=1 – Bruce Adams May 10 '22 at 08:46
0

The used implementation seems to conform to an older specification where returning an error is an allowed behavior for ftruncate(fd, length) when length exceeds the previous length:

If the file previously was smaller than this size, ftruncate() shall either increase the size of the file or fail.

Armali
  • 18,255
  • 14
  • 57
  • 171