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:
authorChristopher Faylor <me@cgf.cx>2001-07-17 07:41:52 +0400
committerChristopher Faylor <me@cgf.cx>2001-07-17 07:41:52 +0400
commit5457dfcb8174f0ff25a0522050c1d79e710a68df (patch)
tree65df1229b3c4d86e54d861f70fc1f2458edc4736
parent30640285c33dedac2099ebd0492b86b3bbabaaad (diff)
* child_info.h: Bump magic number.
(class child_info): Add an element. * cygheap.cc (init_cheap): Allocate cygwin heap in shared memory area. (cygheap_fixup_in_child): Map cygwin heap, passed from parent via shared memory into correct address. (cygheap_setup_for_child): New function. * cygheap.h: Declare new functions. * dcrt0.cc (dll_crt0_1): Accomodate new cygheap_fixup_in_child arguments. Avoid protecting subproc_ready unless it is spawn/nowait. * fork.cc (fork_parent): Use new cygheap_setup_for_child function to setup cygwin heap info. Close passed cygheap shared memory handle. * spawn.cc (spawn_guts): Ditto. Also, reorganize to avoid synchronization between parent and child in non-P_OVERLAY case. * sigproc.cc (wait_sig): Only signal subproc_ready when execing.
-rw-r--r--winsup/cygwin/ChangeLog17
-rw-r--r--winsup/cygwin/child_info.h3
-rw-r--r--winsup/cygwin/cygheap.cc141
-rw-r--r--winsup/cygwin/cygheap.h4
-rw-r--r--winsup/cygwin/dcrt0.cc9
-rw-r--r--winsup/cygwin/fork.cc4
-rw-r--r--winsup/cygwin/shared.cc2
-rw-r--r--winsup/cygwin/sigproc.cc3
-rw-r--r--winsup/cygwin/spawn.cc129
9 files changed, 180 insertions, 132 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 6cc15f51d..68b3a5430 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,20 @@
+Mon 16 Jul 2001 10:47:17 PM EDT Christopher Faylor <cgf@cygnus.com>
+
+ * child_info.h: Bump magic number.
+ (class child_info): Add an element.
+ * cygheap.cc (init_cheap): Allocate cygwin heap in shared memory area.
+ (cygheap_fixup_in_child): Map cygwin heap, passed from parent via
+ shared memory into correct address.
+ (cygheap_setup_for_child): New function.
+ * cygheap.h: Declare new functions.
+ * dcrt0.cc (dll_crt0_1): Accomodate new cygheap_fixup_in_child
+ arguments. Avoid protecting subproc_ready unless it is spawn/nowait.
+ * fork.cc (fork_parent): Use new cygheap_setup_for_child function to
+ setup cygwin heap info. Close passed cygheap shared memory handle.
+ * spawn.cc (spawn_guts): Ditto. Also, reorganize to avoid
+ synchronization between parent and child in non-P_OVERLAY case.
+ * sigproc.cc (wait_sig): Only signal subproc_ready when execing.
+
Mon 16 Jul 2001 15:21:00 Corinna Vinschen <corinna@vinschen.de>
* grp.cc: Add missing Copyright date 2001.
diff --git a/winsup/cygwin/child_info.h b/winsup/cygwin/child_info.h
index 5c9904e61..c838ceda6 100644
--- a/winsup/cygwin/child_info.h
+++ b/winsup/cygwin/child_info.h
@@ -12,7 +12,7 @@ details. */
enum
{
- PROC_MAGIC = 0xaf0ff000,
+ PROC_MAGIC = 0xaf10f000,
PROC_FORK = PROC_MAGIC + 1,
PROC_EXEC = PROC_MAGIC + 2,
PROC_SPAWN = PROC_MAGIC + 3,
@@ -39,6 +39,7 @@ public:
HANDLE pppid_handle;
init_cygheap *cygheap;
void *cygheap_max;
+ HANDLE cygheap_h;
};
class child_info_fork: public child_info
diff --git a/winsup/cygwin/cygheap.cc b/winsup/cygwin/cygheap.cc
index e22a91060..37350b1dd 100644
--- a/winsup/cygwin/cygheap.cc
+++ b/winsup/cygwin/cygheap.cc
@@ -17,6 +17,7 @@
#include "fhandler.h"
#include "dtable.h"
#include "cygheap.h"
+#include "child_info.h"
#include "heap.h"
#include "cygerrno.h"
#include "sync.h"
@@ -28,15 +29,98 @@ void NO_COPY *cygheap_max = NULL;
static NO_COPY muto *cygheap_protect = NULL;
+struct cygheap_entry
+ {
+ int type;
+ struct cygheap_entry *next;
+ char data[0];
+ };
+
+#define NBUCKETS 32
+char *buckets[NBUCKETS] = {0};
+
+#define N0 ((_cmalloc_entry *) NULL)
+#define to_cmalloc(s) ((_cmalloc_entry *) (((char *) (s)) - (int) (N0->data)))
+
+extern "C" {
+static void __stdcall _cfree (void *ptr) __attribute__((regparm(1)));
+}
+
inline static void
init_cheap ()
{
- cygheap = (init_cygheap *) VirtualAlloc (NULL, CYGHEAPSIZE, MEM_RESERVE, PAGE_NOACCESS);
+ HANDLE cygheap_h;
+ cygheap_h = CreateFileMapping (INVALID_HANDLE_VALUE, &sec_none_nih,
+ PAGE_READWRITE | SEC_RESERVE, 0, CYGHEAPSIZE,
+ NULL);
+ cygheap = (init_cygheap *) MapViewOfFileEx (cygheap_h,
+ FILE_MAP_READ | FILE_MAP_WRITE,
+ 0, 0, 0, NULL);
+ CloseHandle (cygheap_h);
if (!cygheap)
api_fatal ("Couldn't reserve space for cygwin's heap, %E");
cygheap_max = cygheap + 1;
}
+void __stdcall
+cygheap_setup_for_child (child_info *ci)
+{
+ void *newcygheap;
+ cygheap_protect->acquire ();
+ unsigned n = (char *) cygheap_max - (char *) cygheap;
+ ci->cygheap_h = CreateFileMapping (INVALID_HANDLE_VALUE, &sec_none,
+ PAGE_READWRITE | SEC_RESERVE, 0,
+ CYGHEAPSIZE, NULL);
+ newcygheap = MapViewOfFileEx (ci->cygheap_h, FILE_MAP_READ | FILE_MAP_WRITE,
+ 0, 0, 0, NULL);
+ if (!VirtualAlloc (newcygheap, n, MEM_COMMIT, PAGE_READWRITE))
+ api_fatal ("couldn't allocate new heap for child, %E");
+ memcpy (newcygheap, cygheap, n);
+ UnmapViewOfFile (newcygheap);
+ ci->cygheap = cygheap;
+ ci->cygheap_max = cygheap_max;
+ ProtectHandle1 (ci->cygheap_h, passed_cygheap_h);
+ cygheap_protect->release ();
+ return;
+}
+
+/* Called by fork or spawn to reallocate cygwin heap */
+void __stdcall
+cygheap_fixup_in_child (child_info *ci, bool execed)
+{
+ cygheap = ci->cygheap;
+ cygheap_max = ci->cygheap_max;
+#if 0
+ if (!DuplicateHandle (hMainProc, ci->cygheap_h,
+ hMainProc, &cygheap_h, 0, 0,
+ DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE))
+ cygheap_h = ci->cygheap_h;
+#endif
+ if (MapViewOfFileEx (ci->cygheap_h, FILE_MAP_READ | FILE_MAP_WRITE,
+ 0, 0, 0, cygheap) != cygheap)
+ api_fatal ("Couldn't allocate space for child's heap from %p, to %p, %E",
+ cygheap, cygheap_max);
+
+ ForceCloseHandle1 (ci->cygheap_h, passed_cygheap_h);
+ cygheap_init ();
+
+ if (execed)
+ {
+ /* Walk the allocated memory chain looking for orphaned memory from
+ previous execs */
+ for (_cmalloc_entry *rvc = cygheap->chain; rvc; rvc = rvc->prev)
+ {
+ cygheap_entry *ce = (cygheap_entry *) rvc->data;
+ if (rvc->b >= NBUCKETS || ce->type <= HEAP_1_START)
+ continue;
+ else if (ce->type < HEAP_1_MAX)
+ ce->type += HEAP_1_MAX; /* Mark for freeing after next exec */
+ else
+ _cfree (ce); /* Marked by parent for freeing in child */
+ }
+ }
+}
+
#define pagetrunc(x) ((void *) (((DWORD) (x)) & ~(4096 - 1)))
static void *__stdcall
@@ -76,12 +160,6 @@ cygheap_init ()
/* Copyright (C) 1997, 2000 DJ Delorie */
-#define NBUCKETS 32
-char *buckets[NBUCKETS] = {0};
-
-#define N0 ((_cmalloc_entry *) NULL)
-#define to_cmalloc(s) ((_cmalloc_entry *) (((char *) (s)) - (int) (N0->data)))
-
static void *_cmalloc (int size) __attribute ((regparm(1)));
static void *__stdcall _crealloc (void *ptr, int size) __attribute ((regparm(2)));
@@ -115,7 +193,6 @@ _cmalloc (int size)
return rvc->data;
}
-static void __stdcall _cfree (void *ptr) __attribute__((regparm(1)));
static void __stdcall
_cfree (void *ptr)
{
@@ -150,57 +227,9 @@ _crealloc (void *ptr, int size)
#define sizeof_cygheap(n) ((n) + sizeof(cygheap_entry))
-struct cygheap_entry
- {
- int type;
- struct cygheap_entry *next;
- char data[0];
- };
-
#define N ((cygheap_entry *) NULL)
#define tocygheap(s) ((cygheap_entry *) (((char *) (s)) - (int) (N->data)))
-/* Called by fork or spawn to reallocate cygwin heap */
-extern "C" void __stdcall
-cygheap_fixup_in_child (HANDLE parent, bool execed)
-{
- DWORD m, n;
- n = (DWORD) cygheap_max - (DWORD) cygheap;
-
- /* Reserve cygwin heap in same spot as parent */
- if (!VirtualAlloc (cygheap, CYGHEAPSIZE, MEM_RESERVE, PAGE_NOACCESS))
- api_fatal ("Couldn't reserve space for cygwin's heap (%p) in child, cygheap, %E", cygheap);
-
- /* Allocate same amount of memory as parent */
- if (!VirtualAlloc (cygheap, n, MEM_COMMIT, PAGE_READWRITE))
- api_fatal ("Couldn't allocate space for child's heap %p, size %d, %E",
- cygheap, n);
-
- /* Copy memory from the parent */
- m = 0;
- if (!ReadProcessMemory (parent, cygheap, cygheap, n, &m) || m != n)
- api_fatal ("Couldn't read parent's cygwin heap %d bytes != %d, %E",
- n, m);
-
- cygheap_init ();
-
- if (execed)
- {
- /* Walk the allocated memory chain looking for orphaned memory from
- previous execs */
- for (_cmalloc_entry *rvc = cygheap->chain; rvc; rvc = rvc->prev)
- {
- cygheap_entry *ce = (cygheap_entry *) rvc->data;
- if (rvc->b >= NBUCKETS || ce->type <= HEAP_1_START)
- continue;
- else if (ce->type < HEAP_1_MAX)
- ce->type += HEAP_1_MAX; /* Mark for freeing after next exec */
- else
- _cfree (ce); /* Marked by parent for freeing in child */
- }
- }
-}
-
inline static void *
creturn (cygheap_types x, cygheap_entry * c, int len)
{
diff --git a/winsup/cygwin/cygheap.h b/winsup/cygwin/cygheap.h
index a32085d58..0f7c917a4 100644
--- a/winsup/cygwin/cygheap.h
+++ b/winsup/cygwin/cygheap.h
@@ -166,9 +166,11 @@ struct init_cygheap
extern init_cygheap *cygheap;
extern void *cygheap_max;
+class child_info;
+void __stdcall cygheap_setup_for_child (child_info *ci) __attribute__ ((regparm(1)));
+void __stdcall cygheap_fixup_in_child (child_info *, bool);
extern "C" {
void __stdcall cfree (void *) __attribute__ ((regparm(1)));
-void __stdcall cygheap_fixup_in_child (HANDLE, bool);
void *__stdcall cmalloc (cygheap_types, DWORD) __attribute__ ((regparm(2)));
void *__stdcall crealloc (void *, DWORD) __attribute__ ((regparm(2)));
void *__stdcall ccalloc (cygheap_types, DWORD, DWORD) __attribute__ ((regparm(3)));
diff --git a/winsup/cygwin/dcrt0.cc b/winsup/cygwin/dcrt0.cc
index cc4986949..8fdae5d8e 100644
--- a/winsup/cygwin/dcrt0.cc
+++ b/winsup/cygwin/dcrt0.cc
@@ -669,13 +669,11 @@ dll_crt0_1 ()
if (child_proc_info)
{
- cygheap = child_proc_info->cygheap;
- cygheap_max = child_proc_info->cygheap_max;
switch (child_proc_info->type)
{
case PROC_FORK:
case PROC_FORK1:
- cygheap_fixup_in_child (child_proc_info->parent, 0);
+ cygheap_fixup_in_child (child_proc_info, 0);
alloc_stack (fork_info);
set_myself (mypid);
user_data->heaptop = child_proc_info->heaptop;
@@ -690,7 +688,7 @@ dll_crt0_1 ()
hexec_proc = spawn_info->hexec_proc;
around:
HANDLE h;
- cygheap_fixup_in_child (spawn_info->parent, 1);
+ cygheap_fixup_in_child (spawn_info, 1);
if (!spawn_info->moreinfo->myself_pinfo ||
!DuplicateHandle (hMainProc, spawn_info->moreinfo->myself_pinfo,
hMainProc, &h, 0, 0,
@@ -709,7 +707,8 @@ dll_crt0_1 ()
old_title = strcpy (title_buf, spawn_info->moreinfo->old_title);
cfree (spawn_info->moreinfo->old_title);
}
- ProtectHandle (child_proc_info->subproc_ready);
+ if (child_proc_info->subproc_ready)
+ ProtectHandle (child_proc_info->subproc_ready);
myself->uid = spawn_info->moreinfo->uid;
if (myself->uid == USHRT_MAX)
cygheap->user.set_sid (NULL);
diff --git a/winsup/cygwin/fork.cc b/winsup/cygwin/fork.cc
index ac9f855e9..5c7bad339 100644
--- a/winsup/cygwin/fork.cc
+++ b/winsup/cygwin/fork.cc
@@ -442,8 +442,7 @@ fork_parent (HANDLE& hParent, dll *&first_dll,
RevertToSelf ();
ch.parent = hParent;
- ch.cygheap = cygheap;
- ch.cygheap_max = cygheap_max;
+ cygheap_setup_for_child (&ch);
#ifdef DEBUGGING
if (npid_max)
{
@@ -477,6 +476,7 @@ out:
&pi);
CloseHandle (hParent);
+ ForceCloseHandle1 (ch.cygheap_h, passed_cygheap_h);
if (!rc)
{
diff --git a/winsup/cygwin/shared.cc b/winsup/cygwin/shared.cc
index be93cfed2..5419fa4d5 100644
--- a/winsup/cygwin/shared.cc
+++ b/winsup/cygwin/shared.cc
@@ -86,7 +86,7 @@ open_shared (const char *name, HANDLE &shared_h, DWORD size, void *addr)
/* Probably win95, so try without specifying the address. */
shared = (shared_info *) MapViewOfFileEx (shared_h,
FILE_MAP_READ|FILE_MAP_WRITE,
- 0,0,0,0);
+ 0, 0, 0, 0);
}
if (!shared)
diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc
index e70a51b3a..051e62eb2 100644
--- a/winsup/cygwin/sigproc.cc
+++ b/winsup/cygwin/sigproc.cc
@@ -1103,8 +1103,7 @@ wait_sig (VOID *)
* windows process waiting to see if it's started a cygwin process or not.
* Signalling subproc_ready indicates that we are a cygwin process.
*/
- if (child_proc_info &&
- (child_proc_info->type == PROC_EXEC || child_proc_info->type == PROC_SPAWN))
+ if (child_proc_info && child_proc_info->type == PROC_EXEC)
{
debug_printf ("subproc_ready %p", child_proc_info->subproc_ready);
if (!SetEvent (child_proc_info->subproc_ready))
diff --git a/winsup/cygwin/spawn.cc b/winsup/cygwin/spawn.cc
index d461e532b..059e070a0 100644
--- a/winsup/cygwin/spawn.cc
+++ b/winsup/cygwin/spawn.cc
@@ -327,8 +327,14 @@ spawn_guts (HANDLE hToken, const char * prog_arg, const char *const *argv,
else
chtype = PROC_EXEC;
- HANDLE spr = CreateEvent (&sec_all, TRUE, FALSE, NULL);
- ProtectHandle (spr);
+ HANDLE spr;
+ if (mode != _P_OVERLAY)
+ spr = NULL;
+ else
+ {
+ spr = CreateEvent (&sec_all, TRUE, FALSE, NULL);
+ ProtectHandle (spr);
+ }
init_child_info (chtype, &ciresrv, (mode == _P_OVERLAY) ? myself->pid : 1, spr);
if (!DuplicateHandle (hMainProc, hMainProc, hMainProc, &ciresrv.parent, 0, 1,
@@ -572,8 +578,7 @@ skip_arg_parsing:
else
envblock = winenv (envp, 0);
- ciresrv.cygheap = cygheap;
- ciresrv.cygheap_max = cygheap_max;
+ cygheap_setup_for_child (&ciresrv);
/* Preallocated buffer for `sec_user' call */
char sa_buf[1024];
@@ -669,6 +674,7 @@ skip_arg_parsing:
MALLOC_CHECK;
if (envblock)
free (envblock);
+ ForceCloseHandle1 (ciresrv.cygheap_h, passed_cygheap_h);
MALLOC_CHECK;
/* Set errno now so that debugging messages from it appear before our
@@ -741,88 +747,83 @@ skip_arg_parsing:
DWORD res;
BOOL exited;
- HANDLE waitbuf[3] = {pi.hProcess, signal_arrived, spr};
- int nwait = 3;
- bool saw_signal = 0;
-
res = 0;
exited = FALSE;
MALLOC_CHECK;
- for (int i = 0; i < 100; i++)
+ if (mode == _P_OVERLAY)
{
- switch (WaitForMultipleObjects (nwait, waitbuf, FALSE, INFINITE))
+ int nwait = 3;
+ HANDLE waitbuf[3] = {pi.hProcess, signal_arrived, spr};
+ for (int i = 0; i < 100; i++)
{
- case WAIT_OBJECT_0:
- sigproc_printf ("subprocess exited");
- DWORD exitcode;
- if (!GetExitCodeProcess (pi.hProcess, &exitcode))
- exitcode = 1;
- res |= exitcode;
- exited = TRUE;
- break;
- case WAIT_OBJECT_0 + 1:
- sigproc_printf ("signal arrived");
- reset_signal_arrived ();
- saw_signal = 1;
- continue;
- case WAIT_OBJECT_0 + 2:
- if (mode == _P_OVERLAY)
+ switch (WaitForMultipleObjects (nwait, waitbuf, FALSE, INFINITE))
{
+ case WAIT_OBJECT_0:
+ sigproc_printf ("subprocess exited");
+ DWORD exitcode;
+ if (!GetExitCodeProcess (pi.hProcess, &exitcode))
+ exitcode = 1;
+ res |= exitcode;
+ exited = TRUE;
+ break;
+ case WAIT_OBJECT_0 + 1:
+ sigproc_printf ("signal arrived");
+ reset_signal_arrived ();
+ continue;
+ case WAIT_OBJECT_0 + 2:
if (myself->ppid_handle)
res |= EXIT_REPARENTING;
if (!my_parent_is_alive ())
{
- nwait = 1;
+ nwait = 2;
sigproc_terminate ();
continue;
}
+ break;
+ case WAIT_FAILED:
+ system_printf ("wait failed: nwait %d, pid %d, winpid %d, %E",
+ nwait, myself->pid, myself->dwProcessId);
+ system_printf ("waitbuf[0] %p %d", waitbuf[0],
+ WaitForSingleObject (waitbuf[0], 0));
+ system_printf ("waitbuf[1] %p = %d", waitbuf[1],
+ WaitForSingleObject (waitbuf[1], 0));
+ system_printf ("waitbuf[w] %p = %d", waitbuf[2],
+ WaitForSingleObject (waitbuf[2], 0));
+ set_errno (ECHILD);
+ try_to_debug ();
+ return -1;
}
break;
- case WAIT_FAILED:
- system_printf ("wait failed: nwait %d, pid %d, winpid %d, %E",
- nwait, myself->pid, myself->dwProcessId);
- system_printf ("waitbuf[0] %p %d", waitbuf[0],
- WaitForSingleObject (waitbuf[0], 0));
- system_printf ("waitbuf[1] %p = %d", waitbuf[1],
- WaitForSingleObject (waitbuf[1], 0));
- system_printf ("waitbuf[w] %p = %d", waitbuf[2],
- WaitForSingleObject (waitbuf[2], 0));
- set_errno (ECHILD);
- try_to_debug ();
- return -1;
}
- break;
- }
- ForceCloseHandle (spr);
+ ForceCloseHandle (spr);
- sigproc_printf ("res = %x", res);
+ sigproc_printf ("res = %x", res);
- if (mode == _P_OVERLAY && (res & EXIT_REPARENTING))
- {
- /* Try to reparent child process.
- * Make handles to child available to parent process and exit with
- * EXIT_REPARENTING status. Wait() syscall in parent will then wait
- * for newly created child.
- */
- HANDLE oldh = myself->hProcess;
- HANDLE h = myself->ppid_handle;
- sigproc_printf ("parent handle %p", h);
- int rc = DuplicateHandle (hMainProc, pi.hProcess, h, &myself->hProcess,
- 0, FALSE, DUPLICATE_SAME_ACCESS);
- sigproc_printf ("%d = DuplicateHandle, oldh %p, newh %p",
- rc, oldh, myself->hProcess);
- if (!rc && my_parent_is_alive ())
+ if (res & EXIT_REPARENTING)
{
- system_printf ("Reparent failed, parent handle %p, %E", h);
- system_printf ("my dwProcessId %d, myself->dwProcessId %d",
- GetCurrentProcessId (), myself->dwProcessId);
- system_printf ("old hProcess %p, hProcess %p", oldh, myself->hProcess);
+ /* Try to reparent child process.
+ * Make handles to child available to parent process and exit with
+ * EXIT_REPARENTING status. Wait() syscall in parent will then wait
+ * for newly created child.
+ */
+ HANDLE oldh = myself->hProcess;
+ HANDLE h = myself->ppid_handle;
+ sigproc_printf ("parent handle %p", h);
+ int rc = DuplicateHandle (hMainProc, pi.hProcess, h, &myself->hProcess,
+ 0, FALSE, DUPLICATE_SAME_ACCESS);
+ sigproc_printf ("%d = DuplicateHandle, oldh %p, newh %p",
+ rc, oldh, myself->hProcess);
+ if (!rc && my_parent_is_alive ())
+ {
+ system_printf ("Reparent failed, parent handle %p, %E", h);
+ system_printf ("my dwProcessId %d, myself->dwProcessId %d",
+ GetCurrentProcessId (), myself->dwProcessId);
+ system_printf ("old hProcess %p, hProcess %p", oldh, myself->hProcess);
+ }
}
- }
- if (saw_signal && mode != _P_OVERLAY)
- thisframe.call_signal_handler ();
+ }
MALLOC_CHECK;