newlib-cygwin/winsup/cygwin/mmap.cc

482 lines
10 KiB
C++
Raw Normal View History

2000-02-18 03:38:33 +08:00
/* mmap.cc
Copyright 1996, 1997, 1998, 2000 Cygnus Solutions.
This file is part of Cygwin.
This software is a copyrighted work licensed under the terms of the
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
details. */
#include "winsup.h"
2000-02-18 03:38:33 +08:00
#include <stdlib.h>
#include <stddef.h>
#include <sys/mman.h>
#include <errno.h>
#include "fhandler.h"
#include "dtable.h"
#include "cygerrno.h"
#include "thread.h"
#include "sync.h"
#include "sigproc.h"
#include "pinfo.h"
#include "security.h"
2000-02-18 03:38:33 +08:00
/*
* Simple class used to keep a record of all current
* mmap areas in a process. Needed so that
* they can be duplicated after a fork().
*/
class mmap_record
{
private:
HANDLE mapping_handle_;
DWORD access_mode_;
DWORD offset_;
DWORD size_to_map_;
void *base_address_;
public:
mmap_record (HANDLE h, DWORD ac, DWORD o, DWORD s, void *b) :
mapping_handle_ (h), access_mode_ (ac), offset_ (o),
size_to_map_ (s), base_address_ (b) { ; }
/* Default Copy constructor/operator=/destructor are ok */
/* Simple accessors */
HANDLE get_handle () const { return mapping_handle_; }
DWORD get_access () const { return access_mode_; }
DWORD get_offset () const { return offset_; }
DWORD get_size () const { return size_to_map_; }
void *get_address () const { return base_address_; }
};
class list {
public:
mmap_record *recs;
int nrecs, maxrecs;
int fd;
list ();
~list ();
void add_record (mmap_record r);
void erase (int i);
};
list::list ()
{
recs = (mmap_record *) malloc (10 * sizeof(mmap_record));
nrecs = 0;
maxrecs = 10;
fd = 0;
}
list::~list ()
{
free (recs);
}
void
list::add_record (mmap_record r)
{
if (nrecs == maxrecs)
{
maxrecs += 5;
recs = (mmap_record *) realloc (recs, maxrecs * sizeof (mmap_record));
}
recs[nrecs++] = r;
}
void
list::erase (int i)
{
for (; i < nrecs-1; i++)
2000-02-18 03:38:33 +08:00
recs[i] = recs[i+1];
nrecs--;
}
class map {
public:
list **lists;
int nlists, maxlists;
map ();
~map ();
list *get_list_by_fd (int fd);
list *add_list (list *l, int fd);
void erase (int i);
};
map::map ()
{
lists = (list **) malloc (10 * sizeof(list *));
nlists = 0;
maxlists = 10;
}
map::~map ()
{
free (lists);
}
list *
map::get_list_by_fd (int fd)
{
int i;
for (i=0; i<nlists; i++)
if (lists[i]->fd == fd)
return lists[i];
return 0;
}
list *
map::add_list (list *l, int fd)
{
l->fd = fd;
if (nlists == maxlists)
{
maxlists += 5;
lists = (list **) realloc (lists, maxlists * sizeof (list *));
}
lists[nlists++] = l;
return lists[nlists-1];
}
void
map::erase (int i)
{
for (; i < nlists-1; i++)
2000-02-18 03:38:33 +08:00
lists[i] = lists[i+1];
nlists--;
}
/*
* Code to keep a record of all mmap'ed areas in a process.
* Needed to duplicate tham in a child of fork().
* mmap_record classes are kept in an STL list in an STL map, keyed
* by file descriptor. This is *NOT* duplicated accross a fork(), it
* needs to be specially handled by the fork code.
*/
static NO_COPY map *mmapped_areas;
extern "C"
caddr_t
mmap (caddr_t addr, size_t len, int prot, int flags, int fd, off_t off)
{
syscall_printf ("addr %x, len %d, prot %x, flags %x, fd %d, off %d",
addr, len, prot, flags, fd, off);
SetResourceLock(LOCK_MMAP_LIST,READ_LOCK|WRITE_LOCK," mmap");
/* Windows 95 does not have fixed addresses */
if ((os_being_run != winNT) && (flags & MAP_FIXED))
{
set_errno (EINVAL);
syscall_printf ("-1 = mmap(): win95 and MAP_FIXED");
return (caddr_t) -1;
}
if (mmapped_areas == 0)
{
/* First mmap call, create STL map */
mmapped_areas = new map;
if (mmapped_areas == 0)
{
set_errno (ENOMEM);
syscall_printf ("-1 = mmap(): ENOMEM");
return (caddr_t) -1;
}
}
DWORD access = (prot & PROT_WRITE) ? FILE_MAP_WRITE : FILE_MAP_READ;
if (flags & MAP_PRIVATE)
access = FILE_MAP_COPY;
DWORD protect;
if (access & FILE_MAP_COPY)
protect = PAGE_WRITECOPY;
else if (access & FILE_MAP_WRITE)
protect = PAGE_READWRITE;
else
protect = PAGE_READONLY;
HANDLE hFile;
if (fd == -1)
hFile = (HANDLE) 0xFFFFFFFF;
else
{
/* Ensure that fd is open */
if (fdtab.not_open (fd))
2000-02-18 03:38:33 +08:00
{
set_errno (EBADF);
syscall_printf ("-1 = mmap(): EBADF");
* Makefile.in: Add cygheap.o. * child_info.h: Add specific exec class. * cygheap.h: New file. Contains declarations for cygwin heap. * cygheap.cc: New file. Implements cygwin heap functions. * dcrt0.cc (quoted): Simplify due to new method for passing arguments between cygwin programs. (alloc_stack_hard_way): Attempt to handle overlapped stack. (dll_crt0_1): Move child_info processing here. Accomodate new method for passing arguments between cygwin programs. Initialize cygwin heap. Establish __argc and __argv variables. (_dll_crt0): Move most of child_info processing to dll_crt0_1. (cygwin_dll_init): Remove duplication. * dtable.cc (dtable::extend): Allocate dtable using cygwin heap. (dtable::build_fhandler): Ditto for fhandler type being constructed. (dtable::dup_worker): Free new fhandler from cygwin heap on error. (dtable::select_*): Don't assume that this == fdtab. (dtable::linearize_fd_array): Delete. (dtable::delinearize_fd_array): Delete. (dtable::fixup_after_exec): New file. (dtable::vfork_child_dup): Use cygwin heap. (dtable::vfork_parent_restore): Ditto. * dtable.h: Remove obsolete methods. Add new method. * environ.cc (posify): Eliminate already_posix parameter and logic. (envsize): New function. (_addenv): Use envsize. (environ_init): Accept an argument pointing to an existing environment list. If supplied, allocate space for this in the the program's heap. * fhandler.cc (fhandler_base::operator =): Move here from fhandler.h. Use cygwin heap to allocate filenames. (fhandler_base::set_name): Allocate/free names from cygwin heap. (fhandler_base::linearize): Delete. (fhandler_base::de_linearize): Delete. (fhandler_base::operator delete): Free from cygwin heap. (fhandler_base::~fhandler_base): Ditto. * fhandler.h: Accomodate elimination of *linearize and other changes above. * fhandler_console.cc (fhandler_console::fixup_after_exec): Rename from de_linearize. * heap.h: New file. * fhandler_tty.cc (fhandler_tty_slave::fhandler_tty_slave): Use cygwin heap for name. fhandler_tty::fixup_after_exec): Rename from de_linearize. * fork.cc (fork): Call cygheap_fixup_in_child. * heap.cc: Use declarations in heap.h. * malloc.cc: Sprinkle assertions throughout to catch attempts to free/realloc something from the cygwin heap. * path.cc: Throughout, eliminate use of per-thread cache for cwd. Use cwd_* functions rather than cwd_* variables to access cwd_win32 and cwd_posix. (cwd_win32): New function. (cwd_posix): New function. (cwd_hash): New function. (cwd_fixup_after_exec): New function. * path.h: Accomodate path.cc changes. * pinfo.cc (pinfo_init): Accept a pointer to an environment table. Pass this to environ_init. Eliminate old 'title' tests. * pinfo.h: Accomodate above change in argument. * spawn.cc (struct av): New method for building argv list. (av::unshift): New method. (spawn_guts): Allocate everything that the child process needs in the cygwin heap and pass a pointer to this to the child. Build argv list using new method. Eliminate delinearize stuff. * thread.h: Eliminate _cwd_win32 and _cwd_posix buffers. * winsup.h: Eliminate obsolete functions. Add envsize() declaration.
2000-09-03 12:16:35 +08:00
ReleaseResourceLock(LOCK_MMAP_LIST,READ_LOCK|WRITE_LOCK," mmap");
2000-02-18 03:38:33 +08:00
return (caddr_t) -1;
}
hFile = fdtab[fd]->get_handle ();
2000-02-18 03:38:33 +08:00
}
HANDLE h = CreateFileMapping (hFile, &sec_none, protect, 0, len, NULL);
if (h == 0)
{
__seterrno ();
syscall_printf ("-1 = mmap(): CreateFileMapping failed with %E");
ReleaseResourceLock(LOCK_MMAP_LIST,READ_LOCK|WRITE_LOCK," mmap");
return (caddr_t) -1;
}
void *base;
if (flags & MAP_FIXED)
{
base = MapViewOfFileEx (h, access, 0, off, len, addr);
if (base != addr)
{
__seterrno ();
syscall_printf ("-1 = mmap(): MapViewOfFileEx failed with %E");
CloseHandle (h);
* Makefile.in: Add cygheap.o. * child_info.h: Add specific exec class. * cygheap.h: New file. Contains declarations for cygwin heap. * cygheap.cc: New file. Implements cygwin heap functions. * dcrt0.cc (quoted): Simplify due to new method for passing arguments between cygwin programs. (alloc_stack_hard_way): Attempt to handle overlapped stack. (dll_crt0_1): Move child_info processing here. Accomodate new method for passing arguments between cygwin programs. Initialize cygwin heap. Establish __argc and __argv variables. (_dll_crt0): Move most of child_info processing to dll_crt0_1. (cygwin_dll_init): Remove duplication. * dtable.cc (dtable::extend): Allocate dtable using cygwin heap. (dtable::build_fhandler): Ditto for fhandler type being constructed. (dtable::dup_worker): Free new fhandler from cygwin heap on error. (dtable::select_*): Don't assume that this == fdtab. (dtable::linearize_fd_array): Delete. (dtable::delinearize_fd_array): Delete. (dtable::fixup_after_exec): New file. (dtable::vfork_child_dup): Use cygwin heap. (dtable::vfork_parent_restore): Ditto. * dtable.h: Remove obsolete methods. Add new method. * environ.cc (posify): Eliminate already_posix parameter and logic. (envsize): New function. (_addenv): Use envsize. (environ_init): Accept an argument pointing to an existing environment list. If supplied, allocate space for this in the the program's heap. * fhandler.cc (fhandler_base::operator =): Move here from fhandler.h. Use cygwin heap to allocate filenames. (fhandler_base::set_name): Allocate/free names from cygwin heap. (fhandler_base::linearize): Delete. (fhandler_base::de_linearize): Delete. (fhandler_base::operator delete): Free from cygwin heap. (fhandler_base::~fhandler_base): Ditto. * fhandler.h: Accomodate elimination of *linearize and other changes above. * fhandler_console.cc (fhandler_console::fixup_after_exec): Rename from de_linearize. * heap.h: New file. * fhandler_tty.cc (fhandler_tty_slave::fhandler_tty_slave): Use cygwin heap for name. fhandler_tty::fixup_after_exec): Rename from de_linearize. * fork.cc (fork): Call cygheap_fixup_in_child. * heap.cc: Use declarations in heap.h. * malloc.cc: Sprinkle assertions throughout to catch attempts to free/realloc something from the cygwin heap. * path.cc: Throughout, eliminate use of per-thread cache for cwd. Use cwd_* functions rather than cwd_* variables to access cwd_win32 and cwd_posix. (cwd_win32): New function. (cwd_posix): New function. (cwd_hash): New function. (cwd_fixup_after_exec): New function. * path.h: Accomodate path.cc changes. * pinfo.cc (pinfo_init): Accept a pointer to an environment table. Pass this to environ_init. Eliminate old 'title' tests. * pinfo.h: Accomodate above change in argument. * spawn.cc (struct av): New method for building argv list. (av::unshift): New method. (spawn_guts): Allocate everything that the child process needs in the cygwin heap and pass a pointer to this to the child. Build argv list using new method. Eliminate delinearize stuff. * thread.h: Eliminate _cwd_win32 and _cwd_posix buffers. * winsup.h: Eliminate obsolete functions. Add envsize() declaration.
2000-09-03 12:16:35 +08:00
ReleaseResourceLock(LOCK_MMAP_LIST,READ_LOCK|WRITE_LOCK," mmap");
2000-02-18 03:38:33 +08:00
return (caddr_t) -1;
}
}
else
{
base = MapViewOfFile (h, access, 0, off, len);
if (base == 0)
{
__seterrno ();
syscall_printf ("-1 = mmap(): MapViewOfFile failed with %E");
CloseHandle (h);
* Makefile.in: Add cygheap.o. * child_info.h: Add specific exec class. * cygheap.h: New file. Contains declarations for cygwin heap. * cygheap.cc: New file. Implements cygwin heap functions. * dcrt0.cc (quoted): Simplify due to new method for passing arguments between cygwin programs. (alloc_stack_hard_way): Attempt to handle overlapped stack. (dll_crt0_1): Move child_info processing here. Accomodate new method for passing arguments between cygwin programs. Initialize cygwin heap. Establish __argc and __argv variables. (_dll_crt0): Move most of child_info processing to dll_crt0_1. (cygwin_dll_init): Remove duplication. * dtable.cc (dtable::extend): Allocate dtable using cygwin heap. (dtable::build_fhandler): Ditto for fhandler type being constructed. (dtable::dup_worker): Free new fhandler from cygwin heap on error. (dtable::select_*): Don't assume that this == fdtab. (dtable::linearize_fd_array): Delete. (dtable::delinearize_fd_array): Delete. (dtable::fixup_after_exec): New file. (dtable::vfork_child_dup): Use cygwin heap. (dtable::vfork_parent_restore): Ditto. * dtable.h: Remove obsolete methods. Add new method. * environ.cc (posify): Eliminate already_posix parameter and logic. (envsize): New function. (_addenv): Use envsize. (environ_init): Accept an argument pointing to an existing environment list. If supplied, allocate space for this in the the program's heap. * fhandler.cc (fhandler_base::operator =): Move here from fhandler.h. Use cygwin heap to allocate filenames. (fhandler_base::set_name): Allocate/free names from cygwin heap. (fhandler_base::linearize): Delete. (fhandler_base::de_linearize): Delete. (fhandler_base::operator delete): Free from cygwin heap. (fhandler_base::~fhandler_base): Ditto. * fhandler.h: Accomodate elimination of *linearize and other changes above. * fhandler_console.cc (fhandler_console::fixup_after_exec): Rename from de_linearize. * heap.h: New file. * fhandler_tty.cc (fhandler_tty_slave::fhandler_tty_slave): Use cygwin heap for name. fhandler_tty::fixup_after_exec): Rename from de_linearize. * fork.cc (fork): Call cygheap_fixup_in_child. * heap.cc: Use declarations in heap.h. * malloc.cc: Sprinkle assertions throughout to catch attempts to free/realloc something from the cygwin heap. * path.cc: Throughout, eliminate use of per-thread cache for cwd. Use cwd_* functions rather than cwd_* variables to access cwd_win32 and cwd_posix. (cwd_win32): New function. (cwd_posix): New function. (cwd_hash): New function. (cwd_fixup_after_exec): New function. * path.h: Accomodate path.cc changes. * pinfo.cc (pinfo_init): Accept a pointer to an environment table. Pass this to environ_init. Eliminate old 'title' tests. * pinfo.h: Accomodate above change in argument. * spawn.cc (struct av): New method for building argv list. (av::unshift): New method. (spawn_guts): Allocate everything that the child process needs in the cygwin heap and pass a pointer to this to the child. Build argv list using new method. Eliminate delinearize stuff. * thread.h: Eliminate _cwd_win32 and _cwd_posix buffers. * winsup.h: Eliminate obsolete functions. Add envsize() declaration.
2000-09-03 12:16:35 +08:00
ReleaseResourceLock(LOCK_MMAP_LIST,READ_LOCK|WRITE_LOCK," mmap");
2000-02-18 03:38:33 +08:00
return (caddr_t) -1;
}
}
/* Now we should have a successfully mmaped area.
Need to save it so forked children can reproduce it.
*/
mmap_record mmap_rec (h, access, off, len, base);
/* Get list of mmapped areas for this fd, create a new one if
one does not exist yet.
*/
list *l = mmapped_areas->get_list_by_fd (fd);
if (l == 0)
{
/* Create a new one */
l = new list;
if (l == 0)
{
UnmapViewOfFile (base);
CloseHandle (h);
set_errno (ENOMEM);
syscall_printf ("-1 = mmap(): ENOMEM");
* Makefile.in: Add cygheap.o. * child_info.h: Add specific exec class. * cygheap.h: New file. Contains declarations for cygwin heap. * cygheap.cc: New file. Implements cygwin heap functions. * dcrt0.cc (quoted): Simplify due to new method for passing arguments between cygwin programs. (alloc_stack_hard_way): Attempt to handle overlapped stack. (dll_crt0_1): Move child_info processing here. Accomodate new method for passing arguments between cygwin programs. Initialize cygwin heap. Establish __argc and __argv variables. (_dll_crt0): Move most of child_info processing to dll_crt0_1. (cygwin_dll_init): Remove duplication. * dtable.cc (dtable::extend): Allocate dtable using cygwin heap. (dtable::build_fhandler): Ditto for fhandler type being constructed. (dtable::dup_worker): Free new fhandler from cygwin heap on error. (dtable::select_*): Don't assume that this == fdtab. (dtable::linearize_fd_array): Delete. (dtable::delinearize_fd_array): Delete. (dtable::fixup_after_exec): New file. (dtable::vfork_child_dup): Use cygwin heap. (dtable::vfork_parent_restore): Ditto. * dtable.h: Remove obsolete methods. Add new method. * environ.cc (posify): Eliminate already_posix parameter and logic. (envsize): New function. (_addenv): Use envsize. (environ_init): Accept an argument pointing to an existing environment list. If supplied, allocate space for this in the the program's heap. * fhandler.cc (fhandler_base::operator =): Move here from fhandler.h. Use cygwin heap to allocate filenames. (fhandler_base::set_name): Allocate/free names from cygwin heap. (fhandler_base::linearize): Delete. (fhandler_base::de_linearize): Delete. (fhandler_base::operator delete): Free from cygwin heap. (fhandler_base::~fhandler_base): Ditto. * fhandler.h: Accomodate elimination of *linearize and other changes above. * fhandler_console.cc (fhandler_console::fixup_after_exec): Rename from de_linearize. * heap.h: New file. * fhandler_tty.cc (fhandler_tty_slave::fhandler_tty_slave): Use cygwin heap for name. fhandler_tty::fixup_after_exec): Rename from de_linearize. * fork.cc (fork): Call cygheap_fixup_in_child. * heap.cc: Use declarations in heap.h. * malloc.cc: Sprinkle assertions throughout to catch attempts to free/realloc something from the cygwin heap. * path.cc: Throughout, eliminate use of per-thread cache for cwd. Use cwd_* functions rather than cwd_* variables to access cwd_win32 and cwd_posix. (cwd_win32): New function. (cwd_posix): New function. (cwd_hash): New function. (cwd_fixup_after_exec): New function. * path.h: Accomodate path.cc changes. * pinfo.cc (pinfo_init): Accept a pointer to an environment table. Pass this to environ_init. Eliminate old 'title' tests. * pinfo.h: Accomodate above change in argument. * spawn.cc (struct av): New method for building argv list. (av::unshift): New method. (spawn_guts): Allocate everything that the child process needs in the cygwin heap and pass a pointer to this to the child. Build argv list using new method. Eliminate delinearize stuff. * thread.h: Eliminate _cwd_win32 and _cwd_posix buffers. * winsup.h: Eliminate obsolete functions. Add envsize() declaration.
2000-09-03 12:16:35 +08:00
ReleaseResourceLock(LOCK_MMAP_LIST,READ_LOCK|WRITE_LOCK," mmap");
2000-02-18 03:38:33 +08:00
return (caddr_t) -1;
}
l = mmapped_areas->add_list (l, fd);
}
/* Insert into the list */
l->add_record (mmap_rec);
syscall_printf ("%x = mmap() succeeded", base);
ReleaseResourceLock(LOCK_MMAP_LIST,READ_LOCK|WRITE_LOCK," mmap");
return (caddr_t) base;
}
/* munmap () removes an mmapped area. It insists that base area
requested is the same as that mmapped, error if not. */
extern "C"
int
munmap (caddr_t addr, size_t len)
{
syscall_printf ("munmap (addr %x, len %d)", addr, len);
SetResourceLock(LOCK_MMAP_LIST,WRITE_LOCK|READ_LOCK," munmap");
/* Check if a mmap'ed area was ever created */
if (mmapped_areas == 0)
{
syscall_printf ("-1 = munmap(): mmapped_areas == 0");
set_errno (EINVAL);
ReleaseResourceLock(LOCK_MMAP_LIST,WRITE_LOCK|READ_LOCK," munmap");
return -1;
}
/* Iterate through the map, looking for the mmapped area.
Error if not found. */
int it;
for (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)
{
mmap_record rec = l->recs[li];
if (rec.get_address () == addr)
{
/* Unmap the area */
UnmapViewOfFile (addr);
CloseHandle (rec.get_handle ());
/* Delete the entry. */
l->erase (li);
syscall_printf ("0 = munmap(): %x", addr);
* Makefile.in: Add cygheap.o. * child_info.h: Add specific exec class. * cygheap.h: New file. Contains declarations for cygwin heap. * cygheap.cc: New file. Implements cygwin heap functions. * dcrt0.cc (quoted): Simplify due to new method for passing arguments between cygwin programs. (alloc_stack_hard_way): Attempt to handle overlapped stack. (dll_crt0_1): Move child_info processing here. Accomodate new method for passing arguments between cygwin programs. Initialize cygwin heap. Establish __argc and __argv variables. (_dll_crt0): Move most of child_info processing to dll_crt0_1. (cygwin_dll_init): Remove duplication. * dtable.cc (dtable::extend): Allocate dtable using cygwin heap. (dtable::build_fhandler): Ditto for fhandler type being constructed. (dtable::dup_worker): Free new fhandler from cygwin heap on error. (dtable::select_*): Don't assume that this == fdtab. (dtable::linearize_fd_array): Delete. (dtable::delinearize_fd_array): Delete. (dtable::fixup_after_exec): New file. (dtable::vfork_child_dup): Use cygwin heap. (dtable::vfork_parent_restore): Ditto. * dtable.h: Remove obsolete methods. Add new method. * environ.cc (posify): Eliminate already_posix parameter and logic. (envsize): New function. (_addenv): Use envsize. (environ_init): Accept an argument pointing to an existing environment list. If supplied, allocate space for this in the the program's heap. * fhandler.cc (fhandler_base::operator =): Move here from fhandler.h. Use cygwin heap to allocate filenames. (fhandler_base::set_name): Allocate/free names from cygwin heap. (fhandler_base::linearize): Delete. (fhandler_base::de_linearize): Delete. (fhandler_base::operator delete): Free from cygwin heap. (fhandler_base::~fhandler_base): Ditto. * fhandler.h: Accomodate elimination of *linearize and other changes above. * fhandler_console.cc (fhandler_console::fixup_after_exec): Rename from de_linearize. * heap.h: New file. * fhandler_tty.cc (fhandler_tty_slave::fhandler_tty_slave): Use cygwin heap for name. fhandler_tty::fixup_after_exec): Rename from de_linearize. * fork.cc (fork): Call cygheap_fixup_in_child. * heap.cc: Use declarations in heap.h. * malloc.cc: Sprinkle assertions throughout to catch attempts to free/realloc something from the cygwin heap. * path.cc: Throughout, eliminate use of per-thread cache for cwd. Use cwd_* functions rather than cwd_* variables to access cwd_win32 and cwd_posix. (cwd_win32): New function. (cwd_posix): New function. (cwd_hash): New function. (cwd_fixup_after_exec): New function. * path.h: Accomodate path.cc changes. * pinfo.cc (pinfo_init): Accept a pointer to an environment table. Pass this to environ_init. Eliminate old 'title' tests. * pinfo.h: Accomodate above change in argument. * spawn.cc (struct av): New method for building argv list. (av::unshift): New method. (spawn_guts): Allocate everything that the child process needs in the cygwin heap and pass a pointer to this to the child. Build argv list using new method. Eliminate delinearize stuff. * thread.h: Eliminate _cwd_win32 and _cwd_posix buffers. * winsup.h: Eliminate obsolete functions. Add envsize() declaration.
2000-09-03 12:16:35 +08:00
ReleaseResourceLock(LOCK_MMAP_LIST,WRITE_LOCK|READ_LOCK," munmap");
2000-02-18 03:38:33 +08:00
return 0;
}
}
}
}
set_errno (EINVAL);
syscall_printf ("-1 = munmap(): EINVAL");
ReleaseResourceLock(LOCK_MMAP_LIST,WRITE_LOCK|READ_LOCK," munmap");
return -1;
}
/* Sync file with memory. Ignore flags for now. */
extern "C"
int
msync (caddr_t addr, size_t len, int flags)
{
syscall_printf ("addr = %x, len = %d, flags = %x",
addr, len, flags);
if (FlushViewOfFile (addr, len) == 0)
{
syscall_printf ("-1 = msync: %E");
__seterrno ();
return -1;
}
syscall_printf ("0 = msync");
return 0;
}
/* Set memory protection */
extern "C"
int
mprotect (caddr_t addr, size_t len, int prot)
{
DWORD old_prot;
DWORD new_prot = 0;
syscall_printf ("mprotect (addr %x, len %d, prot %x)", addr, len, prot);
if (prot == PROT_NONE)
new_prot = PAGE_NOACCESS;
else
{
switch (prot)
{
case PROT_READ | PROT_WRITE | PROT_EXEC:
new_prot = PAGE_EXECUTE_READWRITE;
break;
case PROT_READ | PROT_WRITE:
new_prot = PAGE_READWRITE;
break;
case PROT_READ | PROT_EXEC:
new_prot = PAGE_EXECUTE_READ;
break;
case PROT_READ:
new_prot = PAGE_READONLY;
break;
default:
syscall_printf ("-1 = mprotect (): invalid prot value");
set_errno (EINVAL);
return -1;
}
}
if (VirtualProtect (addr, len, new_prot, &old_prot) == 0)
{
__seterrno ();
syscall_printf ("-1 = mprotect (): %E");
return -1;
}
syscall_printf ("0 = mprotect ()");
return 0;
}
/*
* Call to re-create all the file mappings in a forked
* child. Called from the child in initialization. At this
* point we are passed a valid mmaped_areas map, and all the
* HANDLE's are valid for the child, but none of the
* mapped areas are in our address space. We need to iterate
* through the map, doing the MapViewOfFile calls.
*/
int __stdcall
recreate_mmaps_after_fork (void *param)
{
map *areas = (map *)param;
void *base;
debug_printf ("recreate_mmaps_after_fork, mmapped_areas %p", areas);
/* Check if a mmapped area was ever created */
if (areas == 0)
return 0;
/* Iterate through the map */
int it;
for (it = 0; it < areas->nlists; ++it)
{
list *l = areas->lists[it];
if (l != 0)
{
int li;
for (li = 0; li < l->nrecs; ++li)
{
mmap_record rec = l->recs[li];
debug_printf ("h %x, access %x, offset %d, size %d, address %p",
rec.get_handle (), rec.get_access (), rec.get_offset (),
rec.get_size (), rec.get_address ());
/* Now re-create the MapViewOfFileEx call */
base = MapViewOfFileEx (rec.get_handle (),
rec.get_access (), 0,
rec.get_offset (),
rec.get_size (),
rec.get_address ());
if (base != rec.get_address ())
{
system_printf ("base address %p fails to match requested address %p",
rec.get_address ());
return -1;
}
}
}
}
/* Now set our mmap record in case the child forks. */
mmapped_areas = areas;
debug_printf ("succeeded");
return 0;
}
/* Set a child mmap ptr from our static one. Used to set child mmap
pointer for fork. */
void __stdcall
* include/cygwin/version.h: Bump DLL minor version number to 5 due to all of the changes below. Redefine process structure to avoid a fixed size table. Redefine pinfo/_pinfo classes. Use these throughout. * dcrt0.cc (dll_crt0_1): Accomodate set_myself argument change. (__api_fatal): Accomodate _pinfo::record_death argument change. * exceptions.cc (really_exit): Ditto. (sig_handle_tty_stop): Use pinfo constructor to access process info. (events_init): Don't create pinfo_mutex since it is no longer required. * external.cc (fillout_pinfo): Use winpids class to iterate over all system pids. (cygwin_internal): lock_pinfo_for_update and unlock_pinfo are now noops. * fhandler_termios.cc (fhandler_termios::set_ctty): Use pinfo constructor to access process info. * fork.cc (fork): Reorganize to initialize child info after the child has started since that is when we know the child's winpid, which is necessary to allocate the pinfo shared memory. * mmap.cc (recreate_mmaps_after_fork): Change arg type to _pinfo. * pinfo.cc: Rename pinfo methods to _pinfo throughout. Eliminate pinfo_list stuff. (set_myself): Accept a pid argument now. Call pinfo initializer to initialize myself. Detect when this is an "execed" process and create an "indirect" pid block. (pinfo_init): Accomodate set_myself arg change. (procinfo): Remove. (pinfo::lock_pinfo): Remove. (pinfo::unlock_pinfo): Remove. (pinfo::init): New method. Allocates shared memory space for process pinfo structure. (pinfo::record_death): Don't call locking functions. (cygwin_winpid_to_pid): Simplify by using new pinfo constructor. (EnumProcessesW95): New function for iterating over processes on Windows 95. (winpids::winpids): New constructor for winpids class. Sets up a list of process ids. (enum_init): Initialize w95/wnt pid enumerators. * shared.cc (shared-info::initialize): Remove pid initialization. * shared.h: Move pinfo stuff into pinfo.h. (class shared_info): Remove pinfo_list element. * signal.cc (kill_worker): Use pinfo constructor to access process info. (kill_pgrp): Ditto. Use winpids methods to access list of processes. * sigproc.cc: Throughout, modify to use _pinfo where appropriate. (proc_exists (pid_t)): New function. Determines if a process exists based on the pid. (proc_exists (_pinfo *p): Use new proc_exists function above. (proc_subproc): Copy pinfo stuff around rather than _pinfo pointers. Try to be careful about releasing shared memory when we don't need it anymore. Remove pinfo locks. (remove_zombies): Remove pinfo memory when zombie is going away. * sigproc.h: Reflect _pinfo/pinfo changes in sigproc.cc. * spawn.cc (spawn_guts): Eliminate pinfo *child argument. Reorganize to only initialize child pinfo after process has been started and we know the windows pid. (_spawnve): Reflect spawn_guts changes. * syscalls.cc (setpgid): Use pinfo constructor to access process info. (getpgid): Ditto. (internal_getlogin): Use _pinfo. * winsup.h: Eliminate pinfo_mutex. Eliminate spawn_guts declaration since it is static now. Reflect set_myself argument change. * include/sys/cygwin.h: Add some PID_* enums to accomodate new pinfo stuff. * include/cygwin/version.h: Update minor version for cygdrive changes below.
2000-07-30 00:24:59 +08:00
set_child_mmap_ptr (_pinfo *child)
2000-02-18 03:38:33 +08:00
{
child->mmap_ptr = (void *) mmapped_areas;
}