fixincl mmap problem on Solaris

Zack Weinberg zack@wolery.cumb.org
Tue Sep 5 09:26:00 GMT 2000


On Tue, Sep 05, 2000 at 09:07:06AM -0700, Bruce Korb wrote:
>
> Anyway, "data_map_size" is specifically one byte larger
> than the specified file, and "man -S2 mmap" says:
>
>   Description
>   ===========
>
>   The function mmap establishes a mapping between a process's address
>   space and a virtual memory object. The format of the call is:
> 
>   pa = mmap(addr, len, prot, flags, fd, off);
>
>   mmap establishes a mapping between the process's address space at
>   an address pa for len bytes to the memory object represented by
>   the file descriptor fd at offset off for len bytes. The value of
>   pa is an implementation-dependent function of the parameter addr
>   and values of flags, further described below. A successful mmap
>   call returns pa as its result.  The address ranges covered by [pa,
>   pa + len] and [off, off + len] must be legitimate for the possible
>   (not necessarily current) address space of a process and the
>   object in question, respectively. mmap cannot grow a file (see
>   ftruncate(S)).

The Solaris version of this manpage does not have the last sentence of
that paragraph.  Instead there is another paragraph immediately following:

     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  was
     created  just  before  the mmap() and has no contents, or if
     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.  In other words, mmap()  can-
     not be used to implicitly extend the length of files.

Much farther below, this is clarified:

     The system will always zero-fill any partial page at the end
     of  an object.  Further, the system will never write out any
     modified portions of the last page of an  object  which  are
     beyond its end.  References to whole pages following the end
     of an object will result in the delivery of a SIGBUS or SIG-
     SEGV  signal.  SIGBUS signals may also be delivered on vari-
     ous file system conditions, including quota exceeded errors.

I would be very surprised if anyone has implemented mmap with
different semantics.  They mean you can get away with expecting a null
at the end of an mmapped file as long as the file size is not an exact
multiple of the system page size.  Graham's Solaris installation does
have a file which is an exact multiple, so you get the SIGBUS when you
try to read byte N+1.

My suggestion would be to notice when the file size is an exact
multiple of the page size, and map a page of /dev/zero right after it
using MAP_FIXED.  If that fails, punt and read the file with read(2).

zw


More information about the Gcc mailing list