5

I am trying to create a shared memory area using examples and documentation I found online. My goal is IPC , so I can make different processes talk to each other.

This my C file

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

int main (int argc, char *argv[])
{

struct stat sb;
off_t len;
char *p;
int fd;

fd = shm_open("test",  O_RDWR | O_CREAT); //,S_IRUSR | S_IWUSR);

if (fd == -1) {
    perror("open");
    return 1;
}

if (fstat(fd, &sb)==-1){
    perror("fstat");
    return 1;
}

/*if (!S_ISREG(sb.st_mode)){
    fprintf(stderr, "%s is not a file\n",fileName);
    return 1;
}*/

p = mmap(0, sb.st_size, PROT_WRITE, MAP_SHARED, fd, 0);
if (p == MAP_FAILED){
    perror("mmap");


    return 1;

}

if (close(fd)==-1) {
    perror("close");
    return 1;

}
for (len = 0; len < sb.st_size; len++) {
    putchar(p[len]);

}

if (munmap(p, sb.st_size) == -1) {
    perror("munmao");
    return 1;
}
fprintf(stderr,"\n");
return 0;
}

The problem is that I am getting a mmap: Invalid argument. I assume something is wrong with fd but have no clue how to fix it, any help would be appreciated. I am on Yosemite using latest XCODE .

Kilon
  • 1,962
  • 3
  • 16
  • 23

2 Answers2

5

You need to extend the size of the shared memory mapping, at least the first time when you create it. Right now its size is 0, and mmap is not going to allow you to make a zero length mapping.

So instead of your fstat() call, do e.g.:

size_t len = 4096;
if (ftruncate(fd, len) == -1) {
    perror("ftruncate");
    return 1;
}

And pass this len to mmap().

nos
  • 223,662
  • 58
  • 417
  • 506
  • I am afraid your code does not work, it gives me "ftruncate: Invalid argument" – Kilon Jan 24 '16 at 10:09
  • 1
    Ok, it works fine on linux, it seems OSX has some weird behavior regarding shm_open/ftruncate, see http://stackoverflow.com/questions/25502229/ftruncate-not-working-on-posix-shared-memory-in-mac-os-x (i.e. you've ran your program several times now, so you'll need to remove the segment first. Also, your shm_open call needs a 3. argument that you commented away, hm_open("test", O_RDWR | O_CREAT,S_IRUSR | S_IWUSR);); – nos Jan 24 '16 at 10:44
  • Thank you for your help. I have commented those segments away just for testing purposes I have tried even with them included. I think I will stick to using just open and refrain from using shm_open because I decided that I would like to store my shared memory to a file too as a backup with msync. – Kilon Jan 24 '16 at 11:01
-4

Your addr parameter is set to 0, which might be reserved. Did you mean to use NULL? This would be different than 0.

  • 2
    Downvote also from me because you need to take a look at how mmap work, before providing an answer. 0 is the most used adress for mmap and if the adress is occupied the kernel will find a free adress. – Kilon Jan 24 '16 at 10:14
  • [`NULL` *is* `0`](https://stackoverflow.com/a/7016898/364696); they'd behave the same here. – ShadowRanger Dec 17 '22 at 17:53