Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

laprej

macrumors regular
Original poster
Oct 14, 2005
108
2
Troy, NY
The intent of this code is to create a posix shared memory segment, open it in RW mode using mmap(), then open the same segment in private mode so I get the copy-on-write functionality.

Can anyone see what I'm doing wrong in this code? It compiles and runs fine under Linux but after outputting "debug 1" I get
errno is 22
Invalid argument

(It's mostly just error-checking code below

Code:
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>

#define SIZE 4*4096

#define HANDLE "/tmpmem2"

int main(void) {
    int err = EXIT_SUCCESS;
    
    int fd = shm_open(HANDLE, O_RDWR | O_CREAT, 0777);
    
    if (fd == -1) {
        perror(NULL);
        err = -1;
        goto end;
    }
    
    printf("Page size is %ld\n", sysconf(_SC_PAGESIZE));
    
    int r = ftruncate(fd, SIZE);
    if (r == -1) {
        printf("errno is %d\n", errno);
        perror(NULL);
        err = -1;
        goto unlink;
    }
    
    printf("fd: %i, r: %i\n", fd, r);
    char *buf = mmap(0, SIZE, PROT_READ | PROT_WRITE,
                    MAP_SHARED, fd, 0);
    if (buf == MAP_FAILED) {
        printf("errno is %d\n", errno);
        perror(NULL);
        err = -1;
        goto unlink;
    }
    printf("buf is %p\n", buf);
    
    printf("debug 0\n");
    buf[SIZE - 2] = 41;
    buf[SIZE - 1] = 42;
    printf("debug 1\n");
    
    char *buf2 = mmap(0, SIZE, PROT_READ | PROT_WRITE,
                      MAP_PRIVATE, fd, 0);
    if (buf2 == MAP_FAILED) {
        printf("errno is %d\n", errno);
        perror(NULL);
        err = -1;
        goto munmap1;
    }
    
    printf("buf2: %p\n", buf2);
    buf2[SIZE - 1] = 43;
    buf[SIZE - 2] = 40;
    printf("buf[-2]: %i, buf[-1]: %i, buf2[-2]: %i, buf2[-1]: %i\n",
           buf[SIZE - 2],
           buf[SIZE - 1],
           buf2[SIZE - 2],
           buf2[SIZE - 1]);
    
munmap2:
    munmap(buf2, SIZE);
    
munmap1:
    munmap(buf, SIZE);
    
unlink:
    shm_unlink(HANDLE);
    
end:
    return err;
}
 

willieva

macrumors 6502
Mar 12, 2010
274
0
This code compiles and runs fine on centos7 gcc 4.8.2

Page size is 4096
fd: 3, r: 0
buf is 0x7f605a6f9000
debug 0
debug 1
buf2: 0x7f605a6f5000
buf[-2]: 40, buf[-1]: 42, buf2[-2]: 41, buf2[-1]: 43
 

laprej

macrumors regular
Original poster
Oct 14, 2005
108
2
Troy, NY
For what it's worth, I found a work-around. In place of shm_open(), I used mkstemp(). Should be more or less the desired functionality.
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.