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
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2001-02-05 15:36:41 +0300
committerCorinna Vinschen <corinna@vinschen.de>2001-02-05 15:36:41 +0300
commitcada03f92f6d9f2126ab8dd094a740bdeb673103 (patch)
treef02da22d4cc6106728321ea62c3a6e7e3e737716 /winsup/cygwin/mmap.cc
parentd4eaf28eb5b96c045e64815d07dd17a66e67ac8a (diff)
* mmap.cc (mmap_record::fixup_map): New method to duplicate
the memory protection in a just forked child. (mmap): Realign gran_len to page boundary only on anonymous mapping before saving in the mmap_record. (munmap): Cleanup code. (msync): Ditto. (fixup_mmaps_after_fork): Ditto. Call mmap_record::fixup_map now.
Diffstat (limited to 'winsup/cygwin/mmap.cc')
-rw-r--r--winsup/cygwin/mmap.cc118
1 files changed, 73 insertions, 45 deletions
diff --git a/winsup/cygwin/mmap.cc b/winsup/cygwin/mmap.cc
index 5f07efd98..afb348e71 100644
--- a/winsup/cygwin/mmap.cc
+++ b/winsup/cygwin/mmap.cc
@@ -82,6 +82,7 @@ class mmap_record
DWORD find_empty (DWORD pages);
DWORD map_map (DWORD off, DWORD len);
BOOL unmap_map (caddr_t addr, DWORD len);
+ void fixup_map (void);
};
DWORD
@@ -171,6 +172,33 @@ mmap_record::unmap_map (caddr_t addr, DWORD len)
return TRUE;
}
+void
+mmap_record::fixup_map ()
+{
+ if (os_being_run != winNT)
+ return;
+
+ DWORD prot, old_prot;
+ switch (access_mode_)
+ {
+ case FILE_MAP_WRITE:
+ prot = PAGE_READWRITE;
+ break;
+ case FILE_MAP_READ:
+ prot = PAGE_READONLY;
+ break;
+ default:
+ prot = PAGE_WRITECOPY;
+ break;
+ }
+
+ for (DWORD off = PAGE_CNT (size_to_map_); off > 0; --off)
+ VirtualProtect (base_address_ + off * getpagesize (),
+ getpagesize (),
+ MAP_ISSET (off - 1) ? prot : PAGE_NOACCESS,
+ &old_prot);
+}
+
class list {
public:
mmap_record *recs;
@@ -444,7 +472,8 @@ mmap (caddr_t addr, size_t len, int prot, int flags, int fd, off_t off)
/* Now we should have a successfully mmapped area.
Need to save it so forked children can reproduce it.
*/
- gran_len = PAGE_CNT (gran_len) * getpagesize ();
+ if (fd == -1)
+ gran_len = PAGE_CNT (gran_len) * getpagesize ();
mmap_record mmap_rec (fd, h, access, gran_off, gran_len, base);
/* Get list of mmapped areas for this fd, create a new one if
@@ -504,29 +533,29 @@ munmap (caddr_t addr, size_t len)
/* Iterate through the map, looking for the mmapped area.
Error if not found. */
- int it;
- for (it = 0; it < mmapped_areas->nlists; ++it)
+ for (int it = 0; it < mmapped_areas->nlists; ++it)
{
list *l = mmapped_areas->lists[it];
if (l != 0)
{
+ int fd = l->fd;
+ fhandler_disk_file fh_paging_file (NULL);
+ fhandler_base *fh;
+
+ if (fd == -1 || fdtab.not_open (fd))
+ {
+ fh_paging_file.set_io_handle (INVALID_HANDLE_VALUE);
+ fh = &fh_paging_file;
+ }
+ else
+ fh = fdtab[fd];
+
off_t li = -1;
- while ((li = l->match(addr, len, li)) >= 0)
+ if ((li = l->match(addr, len, li)) >= 0)
{
mmap_record *rec = l->recs + li;
if (rec->unmap_map (addr, len))
{
- int fd = l->fd;
- fhandler_disk_file fh_paging_file (NULL);
- fhandler_base *fh;
-
- if (fd == -1 || fdtab.not_open (fd))
- {
- fh_paging_file.set_io_handle (INVALID_HANDLE_VALUE);
- fh = &fh_paging_file;
- }
- else
- fh = fdtab[fd];
fh->munmap (rec->get_handle (), addr, len);
/* Delete the entry. */
@@ -577,31 +606,29 @@ msync (caddr_t addr, size_t len, int flags)
/* Iterate through the map, looking for the mmapped area.
Error if not found. */
- int it;
- for (it = 0; it < mmapped_areas->nlists; ++it)
+ for (int it = 0; it < mmapped_areas->nlists; ++it)
{
list *l = mmapped_areas->lists[it];
if (l != 0)
{
- int li;
- for (li = 0; li < l->nrecs; ++li)
+ int fd = l->fd;
+ fhandler_disk_file fh_paging_file (NULL);
+ fhandler_base *fh;
+
+ if (fd == -1 || fdtab.not_open (fd))
{
- mmap_record rec = l->recs[li];
- if (rec.get_address () == addr)
- {
- int fd = l->fd;
- fhandler_disk_file fh_paging_file (NULL);
- fhandler_base *fh;
-
- if (fd == -1 || fdtab.not_open (fd))
- {
- fh_paging_file.set_io_handle (INVALID_HANDLE_VALUE);
- fh = &fh_paging_file;
- }
- else
- fh = fdtab[fd];
+ fh_paging_file.set_io_handle (INVALID_HANDLE_VALUE);
+ fh = &fh_paging_file;
+ }
+ else
+ fh = fdtab[fd];
- int ret = fh->msync (rec.get_handle (), addr, len, flags);
+ for (int li = 0; li < l->nrecs; ++li)
+ {
+ mmap_record *rec = l->recs + li;
+ if (rec->get_address () == addr)
+ {
+ int ret = fh->msync (rec->get_handle (), addr, len, flags);
if (ret)
syscall_printf ("%d = msync(): %E", ret);
@@ -818,30 +845,31 @@ fixup_mmaps_after_fork ()
int li;
for (li = 0; li < l->nrecs; ++li)
{
- mmap_record rec = l->recs[li];
+ mmap_record *rec = l->recs + li;
debug_printf ("fd %d, h %x, access %x, offset %d, size %d, address %p",
- rec.get_fd (), rec.get_handle (), rec.get_access (),
- rec.get_offset (), rec.get_size (), rec.get_address ());
+ rec->get_fd (), rec->get_handle (), rec->get_access (),
+ rec->get_offset (), rec->get_size (), rec->get_address ());
BOOL ret;
fhandler_disk_file fh_paging_file (NULL);
fhandler_base *fh;
- if (rec.get_fd () == -1) /* MAP_ANONYMOUS */
+ if (rec->get_fd () == -1) /* MAP_ANONYMOUS */
fh = &fh_paging_file;
else
- fh = fdtab[rec.get_fd ()];
- ret = fh->fixup_mmap_after_fork (rec.get_handle (),
- rec.get_access (),
- rec.get_offset (),
- rec.get_size (),
- rec.get_address ());
+ fh = fdtab[rec->get_fd ()];
+ ret = fh->fixup_mmap_after_fork (rec->get_handle (),
+ rec->get_access (),
+ rec->get_offset (),
+ rec->get_size (),
+ rec->get_address ());
if (!ret)
{
system_printf ("base address fails to match requested address %p",
- rec.get_address ());
+ rec->get_address ());
return -1;
}
+ rec->fixup_map ();
}
}
}