Search code examples
cmmap

mremap() to \0-terminate a string


I'm using mmap()ed memory in one of my programs. One problem is that mmap()ed memory is not \0-terminated when it is a multiple of the pagesize. So in order to make sure that it is \0-terminated I thought about using the Linux specific mremap(). Hence, my idea in code would be:

buf = mmap(NULL, oldsize, PROT_READ | PROT_WRITE, MAP_SHARED);
buf = mremap(buf, oldsize, oldsize + 1, MREMAP_MAYMOVE);

Would I end up with a null-terminated string?


Solution

  • As the commenter told above, you can add 1 already to the size when calling mmap and there's no need for mremap().

    It is not portable though.

    On Linux it is quite safe to use as Linus Torvalds himself once described that trick in a forum post on the realworldtech website and I can not imagine that he will change that anytime soon, as it would break a lot of code (no link to the post, sorry, realworldtech's forum is not searchable and that post was done 6 or 7 years ago).

    I know with certainty, that this trick doesn't work on Solaris Sparc since a 2010 version of libc. I know that because I got burned by that problem around that time when the library had been updated on our system. I had to bite the bullet and change all our code so that it never tried to touch outside the size of the file. The Solaris man page tells with no uncertain words about that.

    The mmap() function allows [pa, pa + len) to extend beyond the end of the object both at the time of the mmap() and while the mapping persists, such as when the file is created prior to the mmap() call and has no contents, or when the file is truncated. Any reference to addresses beyond the end of the object, however, will result in the delivery of a SIGBUS or SIGSEGV signal. The mmap() function cannot be used to implicitly extend the length of files.

    Emphasis mine.