Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/winsup
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2005-03-08 12:18:47 +0300
committerCorinna Vinschen <corinna@vinschen.de>2005-03-08 12:18:47 +0300
commitd2428633a692d48c4c4c2e4ff677936e2bd612d8 (patch)
tree9c4f62e43a09724051510e5af4521c0e3603c09a /winsup
parent18edcecfbf74f23bffeefcaca1722407f6a9f597 (diff)
* mmap.cc (mmap64): Handle MAP_AUTOGROW flag.
(fhandler_disk_file::mmap): Ditto. Clean conditional for readability. * include/sys/mman.h: Add MAP_AUTOGROW flag. * include/cygwin/version.h: Bump API minor version.
Diffstat (limited to 'winsup')
-rw-r--r--winsup/cygwin/ChangeLog7
-rw-r--r--winsup/cygwin/include/cygwin/version.h3
-rw-r--r--winsup/cygwin/include/sys/mman.h3
-rw-r--r--winsup/cygwin/mmap.cc69
4 files changed, 71 insertions, 11 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index a94ab0a46..eea18c3d4 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,10 @@
+2005-03-07 Corinna Vinschen <corinna@vinschen.de>
+
+ * mmap.cc (mmap64): Handle MAP_AUTOGROW flag.
+ (fhandler_disk_file::mmap): Ditto. Clean conditional for readability.
+ * include/sys/mman.h: Add MAP_AUTOGROW flag.
+ * include/cygwin/version.h: Bump API minor version.
+
2005-03-08 Christopher Faylor <cgf@timesys.com>
* dcrt0.cc (dll_crt0_0): Eliminate muto::init call.
diff --git a/winsup/cygwin/include/cygwin/version.h b/winsup/cygwin/include/cygwin/version.h
index 6d965fdff..6b3ed586b 100644
--- a/winsup/cygwin/include/cygwin/version.h
+++ b/winsup/cygwin/include/cygwin/version.h
@@ -250,12 +250,13 @@ details. */
120: Export basename, dirname.
122: Export statvfs, fstatvfs.
123: Export utmpxname.
+ 124: Add MAP_AUTOGROW flag to mmap.
*/
/* Note that we forgot to bump the api for ualarm, strtoll, strtoull */
#define CYGWIN_VERSION_API_MAJOR 0
-#define CYGWIN_VERSION_API_MINOR 123
+#define CYGWIN_VERSION_API_MINOR 124
/* There is also a compatibity version number associated with the
shared memory regions. It is incremented when incompatible
diff --git a/winsup/cygwin/include/sys/mman.h b/winsup/cygwin/include/sys/mman.h
index 3264739c0..21bf6976d 100644
--- a/winsup/cygwin/include/sys/mman.h
+++ b/winsup/cygwin/include/sys/mman.h
@@ -30,6 +30,9 @@ extern "C" {
#define MAP_FIXED 0x10
#define MAP_ANONYMOUS 0x20
#define MAP_ANON MAP_ANONYMOUS
+/* Non-standard flag */
+#define MAP_AUTOGROW 0x8000 /* Grow underlying object to mapping size.
+ File must be opened for writing. */
#define MAP_FAILED ((void *)-1)
diff --git a/winsup/cygwin/mmap.cc b/winsup/cygwin/mmap.cc
index 9a34ba4d2..e1cda7b44 100644
--- a/winsup/cygwin/mmap.cc
+++ b/winsup/cygwin/mmap.cc
@@ -587,10 +587,12 @@ mmap64 (void *addr, size_t len, int prot, int flags, int fd, _off64_t off)
DWORD high;
DWORD low = GetFileSize (fh->get_handle (), &high);
_off64_t fsiz = ((_off64_t)high << 32) + low;
+
/* Don't allow mappings beginning beyond EOF since Windows can't
- handle that POSIX like. FIXME: Still looking for a good idea
- to allow that nevertheless. */
- if (gran_off >= fsiz)
+ handle that POSIX like, unless MAP_AUTOGROW flag is set, which
+ mimics Windows behaviour. FIXME: Still looking for a good idea
+ to allow that under POSIX rules. */
+ if (gran_off >= fsiz && !(flags & MAP_AUTOGROW))
{
set_errno (ENXIO);
ReleaseResourceLock (LOCK_MMAP_LIST, READ_LOCK | WRITE_LOCK,
@@ -598,10 +600,30 @@ mmap64 (void *addr, size_t len, int prot, int flags, int fd, _off64_t off)
return MAP_FAILED;
}
/* Don't map beyond EOF. Windows would change the file to the
- new length otherwise, in contrast to POSIX. */
+ new length otherwise, in contrast to POSIX. Allow mapping
+ beyon EOF if MAP_AUTOGROW flag is set. */
fsiz -= gran_off;
if (gran_len > fsiz)
- gran_len = fsiz;
+ {
+ if ((flags & MAP_AUTOGROW) && (off - gran_off) + len > fsiz)
+ {
+ /* Check if file has been opened for writing. */
+ if (!(fh->get_access () & GENERIC_WRITE))
+ {
+ set_errno (EINVAL);
+ ReleaseResourceLock (LOCK_MMAP_LIST, READ_LOCK | WRITE_LOCK,
+ "mmap");
+ return MAP_FAILED;
+ }
+ gran_len = (off - gran_off) + len;
+ }
+ else
+ gran_len = fsiz;
+ }
+ /* If the requested len is <= file size, drop the MAP_AUTOGROW flag.
+ This simplifes fhandler::mmap's job. */
+ if ((flags & MAP_AUTOGROW) && gran_len <= fsiz)
+ flags &= ~MAP_AUTOGROW;
}
DWORD access = (prot & PROT_WRITE) ? FILE_MAP_WRITE : FILE_MAP_READ;
@@ -1019,6 +1041,7 @@ fhandler_disk_file::mmap (caddr_t *addr, size_t len, DWORD access,
}
HANDLE h;
+ DWORD high, low;
/* On 9x/ME try first to open the mapping by name when opening a
shared file object. This is needed since 9x/ME only shares
@@ -1037,12 +1060,37 @@ fhandler_disk_file::mmap (caddr_t *addr, size_t len, DWORD access,
debug_printf ("named sharing");
if (!(h = OpenFileMapping (access, TRUE, namebuf)))
- h = CreateFileMapping (get_handle (), &sec_none, protect, 0, 0, namebuf);
+ h = CreateFileMapping (get_handle (), &sec_none, protect, 0, 0,
+ namebuf);
+ }
+ else if (get_handle () == INVALID_HANDLE_VALUE)
+ {
+ /* Standard anonymous mapping needs non-zero len. */
+ h = CreateFileMapping (get_handle (), &sec_none, protect, 0, len, NULL);
+ }
+ else if (flags & MAP_AUTOGROW)
+ {
+ high = (off + len) >> 32;
+ low = (off + len) & UINT32_MAX;
+ /* Auto-grow in CreateFileMapping only works if the protection is
+ PAGE_READWRITE. So, first we call CreateFileMapping with
+ PAGE_READWRITE, then, if the requested protection is different, we
+ close the mapping and reopen it again with the correct protection,
+ *iff* auto-grow worked. */
+ h = CreateFileMapping (get_handle (), &sec_none, PAGE_READWRITE,
+ high, low, NULL);
+ if (h && protect != PAGE_READWRITE)
+ {
+ CloseHandle (h);
+ h = CreateFileMapping (get_handle (), &sec_none, protect,
+ high, low, NULL);
+ }
}
else
- h = CreateFileMapping (get_handle (), &sec_none, protect, 0,
- get_handle () == INVALID_HANDLE_VALUE ? len : 0,
- NULL);
+ {
+ /* Zero len creates mapping for whole file. */
+ h = CreateFileMapping (get_handle (), &sec_none, protect, 0, 0, NULL);
+ }
if (!h)
{
__seterrno ();
@@ -1050,7 +1098,8 @@ fhandler_disk_file::mmap (caddr_t *addr, size_t len, DWORD access,
return INVALID_HANDLE_VALUE;
}
- DWORD high = off >> 32, low = off & UINT32_MAX;
+ high = off >> 32;
+ low = off & UINT32_MAX;
void *base = NULL;
/* If a non-zero address is given, try mapping using the given address first.
If it fails and flags is not MAP_FIXED, try again with NULL address. */