简体   繁体   中英

mmap file with one additional page that is not backed by the file

I need to mmap a file in read-only mode but need an additional page at the end of the mapping that is \\0-ed out. My initial idea was to mmap an additional page and claim it by writing to it.

int file=::open(name,O_RDONLY);
size_t size=lseek(file,0,SEEK_END);
size_t pageSize=::sysconf( _SC_PAGESIZE);
int padding=size%pageSize;
size_t mapSize=size+padding+pageSize;
void* mapping=mmap(0,mapSize,PROT_READ|PROT_WRITE,MAP_PRIVATE,file,0);
*(static_cast<char*>(mapping)+size+padding+1)=0;

However, as stated in the mmap documentation I then get a SIGBUS when I write to the additional page (also when reading from there).

My question is, can I somehow claim an additional page after the file without modifying the actual file?

Linux supports MAP_FIXED flag that forces mmap() segment placement, so all you need is to correctly calculate address call second mmap() that will map anonymous page (currently your calculation of padding is incorrect).

int file = ::open("mmap", O_RDONLY);
size_t size = ::lseek(file, 0, SEEK_END);
size_t pageSize = ::sysconf(_SC_PAGESIZE);

int padding = pageSize - size % pageSize;
size_t mapSize = size + padding;

void* mapping = ::mmap(0, mapSize, PROT_READ | PROT_WRITE, 
                     MAP_PRIVATE, file, 0);
void* lastPage = static_cast<char*>(mapping) + mapSize;

void* mapping2 = ::mmap(lastPage, pageSize, PROT_READ | PROT_WRITE, 
                        MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0);

* static_cast<char*>(mapping ) = 1;
* static_cast<char*>(mapping2) = 1;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM