1

So I am trying to port some code from Linux to Mac OSX. During porting I came across this code.

static void allocZeroMap(unsigned long size, int prot, const char *name)
{
    struct map *newnode;
    int fd;
    char buf[11];

    fd = open("/dev/zero", O_RDWR);
    if (fd == -1) {
        printf("couldn't open /dev/zero\n");
        exit(EXIT_FAILURE);
    }

    newnode = zmalloc(sizeof(struct map));
    newnode->name = strdup(name);
    newnode->size = size;
    newnode->prot = prot;
    newnode->type = INITIAL_MAP;
    newnode->ptr = mmap(NULL, size, prot, MAP_ANONYMOUS | MAP_SHARED, fd, 0);
    if (newnode->ptr == MAP_FAILED) {
        perror("mmap");
        exit(EXIT_FAILURE);
    }

    newnode->name = zmalloc(80);

    sprintf(newnode->name, "anon(%s)", name);

    num_initial_mappings++;

    list_add_tail(&newnode->list, &initial_mappings->list);

    sizeUnit(size, buf);
    printf("mapping[%d]: (zeropage %s) %p (%s)\n",
           num_initial_mappings - 1, name, newnode->ptr, buf);

    close(fd);
}

So I figured that I would need to just switch newnode->ptr = mmap(NULL, size, prot, MAP_ANONYMOUS | MAP_SHARED, fd, 0); to newnode->ptr = mmap(NULL, size, prot, MAP_ANON | MAP_SHARED, fd, 0); because Mac OSX does not have the MAP_ANONYMOUS flag and uses MAP_ANON instead.

But when I run the program, that mmap call fails with Invalid argument. So my next thought was check the man page for what causes Invalid arguments errors. The first cause is that MAP_FIXED is set and the addr argument is not page aligned, but I'm not calling MAP_FIXED. Second it's says it will return Invalid argument if you don't specify either MAP_PRIVATE or MAP_SHARED but I'm using MAP_SHARED so that shouldn't be it. Next it says the len argument must not be negative, so I printed the size variable and ran it and it's a positive value. The final reason is that the offset argument is not page aligned, but I am passing zero so that shouldn't be the problem either.

So next I checked stack overflow and saw this question mmap with /dev/zero . I tried using MAP_FILE instead of MAP_ANON but now I get Operation not supported by device, which the man page says means I am missing MAP_ANON. So I tried adding MAP_ANON so that I have mmap(NULL, size, prot, MAP_FILE | MAP_ANON| MAP_SHARED, fd, 0); but that returns Invalid argument as well.

So how do I mmap /dev/zero on Mac OSX or at least create a zero-filled memory map on Mac OSX?

Community
  • 1
  • 1
2trill2spill
  • 1,333
  • 2
  • 20
  • 41
  • The [Wikipedia page](http://en.wikipedia.org/wiki/Mmap) has an example with the comment _Does not work on OS X, as you can't mmap over /dev/zero_ – Barmar Feb 23 '15 at 17:34
  • If that ends up being the case I will open a bug report with apple, but whats another use case of /dev/zero on Mac OSX if you can't mmap it? – 2trill2spill Feb 23 '15 at 17:38
  • You can use `cat /dev/zero` to get an endless stream of (empty) data. – Barmar Feb 23 '15 at 17:42

1 Answers1

1

You should pass -1 instead of fd as the value of the file descriptor as per mmap() man page. Also as you said MAP_ANON is the correct option for MacOS (at least older versions) and there is not need for MAP_FILE.

semuzaboi
  • 4,972
  • 5
  • 20
  • 35
Jesus
  • 11
  • 1