Bruce Korb wrote: > txtmi->txt_data = mmap (NULL, txtmi->txt_size, prot, flags, txtmi->txt_fd, > 0); ... > /* > * Still here? We have to append a page of NUL's > */ > txtmi->txt_full_size += pgsz; > { > void* pNuls; > > #ifdef MAP_ANONYMOUS > pNuls = mmap ((void*)(((char*)txtmi->txt_data) + txtmi->txt_size), pgsz, > PROT_READ, MAP_SHARED|MAP_ANONYMOUS|MAP_FIXED, 0, 0); > #else > txtmi->txt_zero_fd = open ("/dev/zero", O_RDONLY); > if (txtmi->txt_zero_fd < 0) > pNuls = MAP_FAILED; > > else pNuls = > mmap ((void*)(((char*)txtmi->txt_data) + txtmi->txt_size), pgsz, > PROT_READ, MAP_PRIVATE|MAP_FIXED, txtmi->txt_zero_fd, 0); > #endif > > /* > * If we couldn't map the page of NULs, then the caller can > * figure this out by checking that full_size == size and > * the txt_errno is not zero. > */ > if (pNuls == MAP_FAILED) { > txtmi->txt_errno = errno; > txtmi->txt_full_size = txtmi->txt_size; > }
This is not reliable. You have no guarantee that a page will be available after the area covered by the first mmap. If you're unlucky, the second mmap will supersede a block allocated by malloc or the text segment of a shared library. To do it correctly, you need - first, an anonymous mmap of the entire address range at once, - then, mmap the file with MAP_FIXED to the first portion of this range. Bruno