This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: fixincl mmap problem on Solaris
- To: Zack Weinberg <zack at wolery dot cumb dot org>
- Subject: Re: fixincl mmap problem on Solaris
- From: Bruce Korb <bkorb at sco dot COM>
- Date: Tue, 05 Sep 2000 10:08:50 -0700
- CC: Graham Stott <grahams at redhat dot com>, bkorb at gnu dot org, GNU Compiler <gcc at gcc dot gnu dot org>
- Organization: The Santa Cruz Operation
- References: <39B4DB2D.8EFE0C77@redhat.com> <39B51A2A.7F88605F@sco.com> <20000905092607.G295@wolery.cumb.org>
Zack Weinberg wrote:
>
> 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:
> >...
> > pa = mmap(addr, len, prot, flags, fd, off);
> >
> > .... 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, ...
> [but] 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.
Except that this is utter nonsense. What is the possible point
of extending the map beyond the end of the object if references
to such addresses result in an addressing exception? This is
what POSIX says:
Description
The mmap() function establishes a mapping between the process'
address space and a memory object. The format of the call is as
follows:
pa = mmap(addr, len, prot, flags, fildes, off);
The mmap() function establishes a mapping between the process'
address space at an address, pa, for len bytes to the memory
object represented by the file descriptor fildes at offset off
for len bytes. The value of pa is a function of the parameter
addr and the values of flags. A successful mmap() returns pa
as its result. The address range starting at pa and continuing
for len bytes is legitimate for the possible (not necessarily
current) address space of the process. The range of bytes
starting at off and continuing for len bytes is legitimate for
the possible (but not necessarily current) offsets in the file or
shared memory object represented by fildes.
See:
http://slacvx.slac.stanford.edu/HELP/POSIX/CALLABLE_FUNCTIONS/MMAP/DESCRIPTION
The fact that the committee could not come up with consistent,
unambiguous wording means that there were people on the committee
that were too stubborn to allow a useful-for-text-files definition.
Probably because they already had implementations and preferred
inconsistency to changing their code. Yuck & shame on them.
> 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).
Way too much work. Instead:
data_map_size = stbf.st_size;
...
if ((data_map_size & (PAGESIZE-1)) == 0)
res = BAD_ADDR
else
res = (char*)mmap ((void*)NULL, data_map_size, PROT_READ,
MAP_PRIVATE, data_map_fd, 0);
if (res == (char*)BAD_ADDR)
{
curr_data_mapped = BOOL_FALSE;
res = load_file_data ( fdopen (data_map_fd, "r"));
}