This is the mail archive of the
mailing list for the Cygwin project.
Re: mmap() and gcc precompiled headers
- From: Corinna Vinschen <corinna-cygwin at cygwin dot com>
- To: cygwin at cygwin dot com
- Date: Sat, 5 Jul 2003 15:26:08 +0200
- Subject: Re: mmap() and gcc precompiled headers
- References: <3F05D6B5.email@example.com>
- Reply-to: cygwin at cygwin dot com
On Fri, Jul 04, 2003 at 12:34:13PM -0700, Earl Chew wrote:
> DWORD high;
> DWORD low = GetFileSize (fh->get_handle (), &high);
> __off64_t fsiz = ((__off64_t)high << 32) + low;
> /*1*/ fsiz -= gran_off;
> if (gran_len > fsiz)
> /*2*/ gran_len = fsiz;
> Firstly, gran_off was larger than fsiz. The subtraction at /*1*/
Urgh, isn't that a very strange border case? Who the heck is trying
to establish a mmap with an offset beyond EOF (since that is the case
if gran_off is > filesize)? What's the purpose of that?
> doesn't check for overflow, resulting in fsiz becoming negative.
> This results in gran_len taking on a very strange value. I suspect
> this situation should return with EINVAL or ENXIO.
Yeah, I admit that the above code isn't overly secure...
> Secondly, even if the value does not underflow, there is an
> interesting side-effect to the assignment made at /*2*/. This
> assignment can drastically reduce the value of gran_len.
> The caller is not aware that the actual mapping is much smaller
> than requested. (Should this fail with EOVERFLOW?)
The whole reasoning of the above kludgy statement is to make sure that
gran_off + gran_len is not bigger than GetFileSize, otherwise
MapViewOfFileEx fails. Mapping beyond EOF is impossible on Windows,
How to get this right? Well, it's hard to get it like in Linux.
At least an offset >= filesize is not easily established. I guess
returning EOVERFLOW would be correct according to SUSv3:
The file is a regular file and the value of off plus len exceeds
the offset maximum established in the open file description
associated with fildes.
EINVAL is reserved for invalid addr or flags values. ENXIO is a good
candidate as well:
Addresses in the range [off,off+len) are invalid for the object
specified by fildes.
OTOH, if just off+len >= filesize, then it still should work, methinks.
off_len is reduced to match the filesize as it's currently implemented
and now let's have a look into munmap.
> The munmap() function shall remove any mappings for those
> entire pages containing any part of the address space of
> the process starting at addr and continuing for len bytes.
> Further references to these pages shall result in the generation
> of a SIGSEGV signal to the process. If there are no mappings in
> the specified address range, then munmap() has no effect.
Yes, mulling over this description for a while, I see that the
implementation of munmap isn't quite ok. EINVAL is returned if
no mapping could be unmapped but that's obviously wrong.
I'll rewrite munmap this weekend if I get the chance.
Corinna Vinschen Please, send mails regarding Cygwin to
Cygwin Developer mailto:firstname.lastname@example.org
Red Hat, Inc.
Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple
Problem reports: http://cygwin.com/problems.html