The ultimate goal here is that I would like to expand the size of the shared memory segment and notify processes of reassigning the segment after expansion. However, it seems that calling ftruncate a second time in the shared memory fd is not performed using EINVAL. The only other question I could find about this has no answer: ftruncate failed a second time
The ftruncate and shm_open files do not mention the prohibition of expanding shared memory segments after creation, in fact they seem to indicate that they can be modified using ftruncate, but so far my testing has shown the opposite. The only solution I can think of is to destroy the shared memory segment and recreate it in a larger size, however, this will require all the processes that helped the segment cancel it before the object is destroyed and available for recreation.
Any thoughts? Thanks!
EDIT: as requested as a simple example
#include <stdlib.h> #include <stdio.h> #include <unistd.h> #include <fcntl.h> #include <sys/stat.h> #include <sys/mman.h> #include <sys/types.h> int main(int argc, char *argv[]){ const char * name = "testfile"; size_t sz = 4096; // page size on my sys int fd; if((fd = shm_open(name, O_CREAT | O_RDWR, 0666)) == -1){ perror("shm_open"); exit(1); } ftruncate(fd, sz); perror("First truncate"); ftruncate(fd, 2*sz); perror("second truncate"); shm_unlink(name); return 0; }
Output:
First truncate: Undefined error: 0 second truncate: Invalid argument
EDIT - Answer: It seems that this is a problem with the OSX implementation of the POSIX standard, the above snippet works with the GNU / Linux 3.13.0-53 kernel, and probably others, I would suggest.
source share