OSDN Git Service

* child_info.h (child_info::cygheap_h): Delete.
authorcgf <cgf>
Wed, 1 Jun 2005 03:46:55 +0000 (03:46 +0000)
committercgf <cgf>
Wed, 1 Jun 2005 03:46:55 +0000 (03:46 +0000)
(child_info::dwProcessId): New field.
* cygheap.cc (init_cheap): Delete.
(dup_now): Ditto.
(cygheap_setup_for_child): Ditto.
(cygheap_setup_for_child_cleanup): Ditto.
(cygheap_fixup_in_child): Simplify.  Use new "child_copy" function to copy heap
from parent.
(_csbrk): Don't attempt allocation if within cygheap section.  Fix so that more
than one allocation will succeed.
(cygheap_init): Reset possibly-nonzero region to zero.
* cygheap.h (cygheap_setup_for_child): Delete declaration.
(cygheap_setup_for_child_cleanup): Ditto.
(cygheap_start): Define as an array.
* cygwin.sc: Modernize.  Remove unneeded sections.  Define cygheap here.
* dcrt0.cc (do_exit): Reflect argument change to close_all_files.
* dtable.cc (dtable::vfork_parent_restore): Ditto.
* dtable.h: Ditto.
* fhandler.h: Ditto.
* fork.cc (fork_copy): Call ReadProcessMemory if there is no thread
(indicating that we're execing).
(fork_child): Don't mess with hParent.
(fork_parent): Remove hParent stuff.  It happens earlier now.  Remove call to
cygheap_setup_for_child* stuff.
(fork): Put child_info_stuff in grouped structure.  Issue error if parent
handle is not set.
(child_copy): New function.
* sigproc.cc (child_info::child_info): Put cygheap settings here.  Set parent
handle.
(child_info::~child_info): Close parent handle if it exists.
* spawn.cc (spawn_guts): Reorganize so that ciresrv is allocated at only the
last minute so that cygheap changes are reflected.  Delete cygheap_setup*
calls.
* syscalls.cc (close_all_files): Add an argument to flag when the fd entry
should be released.
* winsup.h (close_all_files): Add an argument to close_all_files declaration.
Declare child_copy.

14 files changed:
winsup/cygwin/ChangeLog
winsup/cygwin/child_info.h
winsup/cygwin/cygheap.cc
winsup/cygwin/cygheap.h
winsup/cygwin/cygwin.sc
winsup/cygwin/dcrt0.cc
winsup/cygwin/dtable.cc
winsup/cygwin/dtable.h
winsup/cygwin/fhandler.h
winsup/cygwin/fork.cc
winsup/cygwin/sigproc.cc
winsup/cygwin/spawn.cc
winsup/cygwin/syscalls.cc
winsup/cygwin/winsup.h

index 924a907..c79e095 100644 (file)
@@ -1,3 +1,44 @@
+2005-05-30  Christopher Faylor  <cgf@timesys.com>
+
+       * child_info.h (child_info::cygheap_h): Delete.
+       (child_info::dwProcessId): New field.
+       * cygheap.cc (init_cheap): Delete.
+       (dup_now): Ditto.
+       (cygheap_setup_for_child): Ditto.
+       (cygheap_setup_for_child_cleanup): Ditto.
+       (cygheap_fixup_in_child): Simplify.  Use new "child_copy" function to
+       copy heap from parent.
+       (_csbrk): Don't attempt allocation if within cygheap section.  Fix so
+       that more than one allocation will succeed.
+       (cygheap_init): Reset possibly-nonzero region to zero.
+       * cygheap.h (cygheap_setup_for_child): Delete declaration.
+       (cygheap_setup_for_child_cleanup): Ditto.
+       (cygheap_start): Define as an array.
+       * cygwin.sc: Modernize.  Remove unneeded sections.  Define cygheap
+       here.
+       * dcrt0.cc (do_exit): Reflect argument change to close_all_files.
+       * dtable.cc (dtable::vfork_parent_restore): Ditto.
+       * dtable.h: Ditto.
+       * fhandler.h: Ditto.
+       * fork.cc (fork_copy): Call ReadProcessMemory if there is no thread
+       (indicating that we're execing).
+       (fork_child): Don't mess with hParent.
+       (fork_parent): Remove hParent stuff.  It happens earlier now.
+       Remove call to cygheap_setup_for_child* stuff.
+       (fork): Put child_info_stuff in grouped structure.  Issue error if
+       parent handle is not set.
+       (child_copy): New function.
+       * sigproc.cc (child_info::child_info): Put cygheap settings here.  Set
+       parent handle.
+       (child_info::~child_info): Close parent handle if it exists.
+       * spawn.cc (spawn_guts): Reorganize so that ciresrv is allocated at
+       only the last minute so that cygheap changes are reflected.  Delete
+       cygheap_setup* calls.
+       * syscalls.cc (close_all_files): Add an argument to flag when the fd
+       entry should be released.
+       * winsup.h (close_all_files): Add an argument to close_all_files
+       declaration.  Declare child_copy.
+
 2005-05-30  Vaclav Haisman  <v.haisman@sh.cvut.cz>
 
        * thread.h (List_remove): Make node parameter const.  Use simple
index f0fa3d0..5e2bc05 100644 (file)
@@ -29,7 +29,7 @@ enum child_info_types
 
 #define EXEC_MAGIC_SIZE sizeof(child_info)
 
-#define CURR_CHILD_INFO_MAGIC 0xd079e02U
+#define CURR_CHILD_INFO_MAGIC 0xd94c588aU
 
 /* NOTE: Do not make gratuitous changes to the names or organization of the
    below class.  The layout is checksummed to determine compatibility between
@@ -48,7 +48,7 @@ public:
   init_cygheap *cygheap;
   void *cygheap_max;
   DWORD cygheap_reserve_sz;
-  HANDLE cygheap_h;
+  DWORD dwProcessId;
   unsigned fhandler_union_cb;
   child_info (unsigned, child_info_types);
   ~child_info ();
index 3695011..5e85a07 100644 (file)
 #include "heap.h"
 #include "sync.h"
 #include "sigproc.h"
+#include "pinfo.h"
+#include <unistd.h>
 
 init_cygheap NO_COPY *cygheap;
 void NO_COPY *cygheap_max;
 
+extern "C" char  _cygheap_mid[] __attribute__((section(".cygheap")));
+extern "C" char  _cygheap_end[] __attribute__((section(".cygheap_end")));
+
 static NO_COPY muto cygheap_protect;
-static NO_COPY DWORD reserve_sz;
 
 struct cygheap_entry
   {
@@ -44,141 +48,20 @@ struct cygheap_entry
 #define MVMAP_OPTIONS (FILE_MAP_WRITE)
 
 extern "C" {
-static void __stdcall _cfree (void *ptr) __attribute__((regparm(1)));
-}
-
-static void
-init_cheap ()
-{
-#ifndef DEBUGGING
-  reserve_sz = CYGHEAPSIZE;
-#else
-  char buf[80];
-  DWORD initial_sz = 0;
-  if (!GetEnvironmentVariable ("CYGWIN_HEAPSIZE", buf, sizeof buf - 1))
-    initial_sz = reserve_sz = CYGHEAPSIZE;
-  else
-    {
-      initial_sz = reserve_sz = atoi (buf);
-      small_printf ("using cygheap size %d\n", reserve_sz);
-    }
-#endif
-  do
-    if ((cygheap = (init_cygheap *) VirtualAlloc ((void *) &_cygheap_start,
-                                                 reserve_sz, MEM_RESERVE,
-                                                 PAGE_NOACCESS)))
-      break;
-  while ((reserve_sz -= 2 * (1024 * 1024)) >= CYGHEAPSIZE_MIN);
-#ifdef DEBUGGING
-  if (reserve_sz != initial_sz)
-    small_printf ("reset initial cygheap size to %u\n", reserve_sz);
-#endif
-  if (!cygheap)
-    {
-      MEMORY_BASIC_INFORMATION m;
-      if (!VirtualQuery ((LPCVOID) &_cygheap_start, &m, sizeof m))
-       system_printf ("couldn't get memory info, %E");
-      system_printf ("Couldn't reserve %d bytes of space for cygwin's heap, %E",
-                    reserve_sz);
-      api_fatal ("AllocationBase %p, BaseAddress %p, RegionSize %p, State %p\n",
-                m.AllocationBase, m.BaseAddress, m.RegionSize, m.State);
-    }
-  cygheap_max = cygheap;
-}
-
-static void dup_now (void *, child_info *, unsigned) __attribute__ ((regparm(3)));
-static void
-dup_now (void *newcygheap, child_info *ci, unsigned n)
-{
-  if (!VirtualAlloc (newcygheap, n, MEM_COMMIT, PAGE_READWRITE))
-    api_fatal ("couldn't allocate new cygwin heap %p, %d for child, %E",
-              newcygheap, n);
-  memcpy (newcygheap, cygheap, n);
-}
-
-void *__stdcall
-cygheap_setup_for_child (child_info *ci, bool dup_later)
-{
-  void *newcygheap;
-  cygheap_protect.acquire ();
-  unsigned n = (char *) cygheap_max - (char *) cygheap;
-  unsigned size = reserve_sz;
-  if (size < n)
-    size = n + (128 * 1024);
-  ci->cygheap_h = CreateFileMapping (INVALID_HANDLE_VALUE, &sec_none,
-                                    CFMAP_OPTIONS, 0, size, NULL);
-  if (!ci->cygheap_h)
-    api_fatal ("Couldn't create heap for child, size %d, %E", size);
-  newcygheap = MapViewOfFileEx (ci->cygheap_h, MVMAP_OPTIONS, 0, 0, 0, NULL);
-  if (!newcygheap)
-    api_fatal ("couldn't map space for new cygheap, %E");
-  ProtectHandle1INH (ci->cygheap_h, passed_cygheap_h);
-  if (!dup_later)
-    dup_now (newcygheap, ci, n);
-  cygheap_protect.release ();
-  ci->cygheap = cygheap;
-  ci->cygheap_max = cygheap_max;
-  ci->cygheap_reserve_sz = size;
-  return newcygheap;
-}
-
-void __stdcall
-cygheap_setup_for_child_cleanup (void *newcygheap, child_info *ci,
-                                bool dup_it_now)
-{
-  if (dup_it_now)
-    {
-      /* NOTE: There is an assumption here that cygheap_max has not changed
-        between the time that cygheap_setup_for_child was called and now.
-        Make sure that this is a correct assumption.  */
-      cygheap_protect.acquire ();
-      dup_now (newcygheap, ci, (char *) cygheap_max - (char *) cygheap);
-      cygheap_protect.release ();
-    }
-  UnmapViewOfFile (newcygheap);
-  ForceCloseHandle1 (ci->cygheap_h, passed_cygheap_h);
+static void __stdcall _cfree (void *) __attribute__((regparm(1)));
+static void *__stdcall _csbrk (int);
 }
 
 /* Called by fork or spawn to reallocate cygwin heap */
 void __stdcall
 cygheap_fixup_in_child (bool execed)
 {
-  cygheap = child_proc_info->cygheap;
-  cygheap_max = child_proc_info->cygheap_max;
-  void *addr = !wincap.map_view_of_file_ex_sucks () ? cygheap : NULL;
-  void *newaddr;
-
-  newaddr = MapViewOfFileEx (child_proc_info->cygheap_h, MVMAP_OPTIONS, 0, 0, 0, addr);
-  reserve_sz = child_proc_info->cygheap_reserve_sz;
-  if (newaddr != cygheap)
-    {
-      if (!newaddr)
-       newaddr = MapViewOfFileEx (child_proc_info->cygheap_h, MVMAP_OPTIONS, 0, 0, 0, NULL);
-      DWORD n = (DWORD) cygheap_max - (DWORD) cygheap;
-      /* Reserve cygwin heap in same spot as parent */
-      if (!VirtualAlloc (cygheap, reserve_sz, MEM_RESERVE, PAGE_NOACCESS))
-       {
-         MEMORY_BASIC_INFORMATION m;
-         memset (&m, 0, sizeof m);
-         if (!VirtualQuery ((LPCVOID) cygheap, &m, sizeof m))
-           system_printf ("couldn't get memory info, %E");
-
-         system_printf ("Couldn't reserve %d bytes of space for cygwin's heap (%p <%p>) in child, %E",
-                        reserve_sz, cygheap, newaddr);
-         api_fatal ("m.AllocationBase %p, m.BaseAddress %p, m.RegionSize %p, m.State %p\n",
-                    m.AllocationBase, m.BaseAddress, m.RegionSize, m.State);
-       }
-
-      /* 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);
-      memcpy (cygheap, newaddr, n);
-      UnmapViewOfFile (newaddr);
-    }
-
-  ForceCloseHandle1 (child_proc_info->cygheap_h, passed_cygheap_h);
-
+  cygheap_max = child_proc_info->cygheap;
+  cygheap = (init_cygheap *) cygheap_max;
+  _csbrk ((char *) child_proc_info->cygheap_max - (char *) cygheap);
+  child_copy (child_proc_info->parent, child_proc_info->dwProcessId, "cygheap", cygheap, cygheap_max);
+  if (execed)
+    CloseHandle (child_proc_info->parent);
   cygheap_init ();
   debug_fixup_after_fork_exec ();
 
@@ -222,30 +105,42 @@ init_cygheap::close_ctty ()
 #endif
 }
 
-#define pagetrunc(x) ((void *) (((DWORD) (x)) & ~(4096 - 1)))
+#define nextpage(x) ((char *) (((DWORD) ((char *) x + granmask)) & ~granmask))
+#define allocsize(x) ((DWORD) nextpage (x))
+#ifdef DEBUGGING
+#define somekinda_printf debug_printf
+#else
+#define somekinda_printf malloc_printf
+#endif
 
 static void *__stdcall
 _csbrk (int sbs)
 {
   void *prebrk = cygheap_max;
-  void *prebrka = pagetrunc (prebrk);
+  size_t granmask = getshmlba () - 1;
+  char *newbase = nextpage (prebrk);
   cygheap_max = (char *) cygheap_max + sbs;
-  if (!sbs || (prebrk != prebrka && prebrka == pagetrunc (cygheap_max)))
+  if (!sbs || (newbase > cygheap_max) || (cygheap_max < _cygheap_end))
     /* nothing to do */;
-  else if (!VirtualAlloc (prebrk, (DWORD) sbs, MEM_COMMIT, PAGE_READWRITE))
+  else
     {
-#ifdef DEBUGGING
-      system_printf ("couldn't commit memory for cygwin heap, prebrk %p, size %d, heapsize now %d, max heap size %u, %E",
-                    prebrk, sbs, (char *) cygheap_max - (char *) cygheap,
-                    reserve_sz);
-#else
-      malloc_printf ("couldn't commit memory for cygwin heap, prebrk %p, size %d, heapsize now %d, max heap size %u, %E",
-                    prebrk, sbs, (char *) cygheap_max - (char *) cygheap,
-                    reserve_sz);
-#endif
-      __seterrno ();
-      cygheap_max = (char *) cygheap_max - sbs;
-      return NULL;
+      if (prebrk <= _cygheap_end)
+       newbase = _cygheap_end;
+
+      DWORD adjsbs = allocsize ((char *) cygheap_max - newbase);
+      if (!VirtualAlloc (newbase, adjsbs, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE))
+       {
+         MEMORY_BASIC_INFORMATION m;
+         if (!VirtualQuery (newbase, &m, sizeof m))
+           system_printf ("couldn't get memory info, %E");
+         somekinda_printf ("Couldn't reserve/commit %d bytes of space for cygwin's heap, %E",
+                           adjsbs);
+         somekinda_printf ("AllocationBase %p, BaseAddress %p, RegionSize %p, State %p\n",
+                           m.AllocationBase, m.BaseAddress, m.RegionSize, m.State);
+         __seterrno ();
+         cygheap_max = (char *) cygheap_max - sbs;
+         return NULL;
+       }
     }
 
   return prebrk;
@@ -257,7 +152,13 @@ cygheap_init ()
   cygheap_protect.init ("cygheap_protect");
   if (!cygheap)
     {
-      init_cheap ();
+#if 1
+      cygheap = (init_cygheap *) memset (_cygheap_start, 0, _cygheap_mid - _cygheap_start);
+#else
+      cygheap = (init_cygheap *) _cygheap_start;
+#endif
+
+      cygheap_max = cygheap;
       (void) _csbrk (sizeof (*cygheap));
     }
   if (!cygheap->fdtab)
index 2e0a1e2..5738d25 100644 (file)
@@ -416,8 +416,6 @@ class cygheap_fdenum : public cygheap_fdmanip
 };
 
 class child_info;
-void *__stdcall cygheap_setup_for_child (child_info *ci, bool dup_later) __attribute__ ((regparm(2)));
-void __stdcall cygheap_setup_for_child_cleanup (void *, child_info *, bool) __attribute__ ((regparm(3)));
 void __stdcall cygheap_fixup_in_child (bool);
 extern "C" {
 void __stdcall cfree (void *) __attribute__ ((regparm(1)));
@@ -428,5 +426,5 @@ char *__stdcall cstrdup (const char *) __attribute__ ((regparm(1)));
 char *__stdcall cstrdup1 (const char *) __attribute__ ((regparm(1)));
 void __stdcall cfree_and_set (char *&, char * = NULL) __attribute__ ((regparm(2)));
 void __stdcall cygheap_init ();
-extern DWORD _cygheap_start __attribute__((section(".cygheap")));
+extern char _cygheap_start[] __attribute__((section(".idata")));
 }
index a911b93..6393dab 100644 (file)
@@ -1,6 +1,4 @@
 OUTPUT_FORMAT(pei-i386)
-SEARCH_DIR(/cygnus/i686-pc-cygwin/lib/w32api); SEARCH_DIR(/cygnus/i686-pc-cygwin/lib);
-ENTRY(_mainCRTStartup)
 SECTIONS
 {
   .text  __image_base__ + __section_alignment__  :
@@ -10,9 +8,9 @@ SECTIONS
     *(SORT(.text$*))
     *(.glue_7t)
     *(.glue_7)
-     ___CTOR_LIST__ = .; __CTOR_LIST__ = . ;
+     ___CTOR_LIST__ = .; __CTOR_LIST__ = .;
                        LONG (-1); *(SORT(.ctors.*)); *(.ctors); *(.ctor); LONG (0);
-     ___DTOR_LIST__ = .; __DTOR_LIST__ = . ;
+     ___DTOR_LIST__ = .; __DTOR_LIST__ = .;
                        LONG (-1); *(SORT(.dtors.*)); *(.dtors); *(.dtor);  LONG (0);
      *(.fini)
     /* ??? Why is .gcc_exc here?  */
@@ -20,38 +18,42 @@ SECTIONS
      etext = .;
     *(.gcc_except_table)
   }
+  .autoload_text ALIGN(__section_alignment__) :
+  {
+    *(.*_text);
+  }
   /* The Cygwin DLL uses a section to avoid copying certain data
      on fork.  This used to be named ".data".  The linker used
      to include this between __data_start__ and __data_end__, but that
      breaks building the cygwin32 dll.  Instead, we name the section
      ".data_cygwin_nocopy" and explictly include it after __data_end__. */
-  .data BLOCK(__section_alignment__) :
+  .data ALIGN(__section_alignment__) :
   {
-    __data_start__ = . ;
+    __data_start__ = .;
     *(.data)
     *(.data2)
     *(SORT(.data$*))
-    __data_end__ = . ;
+    __data_end__ = .;
     *(.data_cygwin_nocopy)
   }
-  .rdata BLOCK(__section_alignment__) :
+  .rdata ALIGN(__section_alignment__) :
   {
     *(.rdata)
     *(SORT(.rdata$*))
     *(.eh_frame)
   }
-  .pdata BLOCK(__section_alignment__) :
+  .pdata ALIGN(__section_alignment__) :
   {
     *(.pdata)
   }
-  .bss BLOCK(__section_alignment__) :
+  .bss ALIGN(__section_alignment__) :
   {
-    __bss_start__ = . ;
+    __bss_start__ = .;
     *(.bss)
     *(COMMON)
-    __bss_end__ = . ;
+    __bss_end__ = .;
   }
-  .edata BLOCK(__section_alignment__) :
+  .edata ALIGN(__section_alignment__) :
   {
     *(.edata)
   }
@@ -62,7 +64,28 @@ SECTIONS
     *(.debug$F)
     *(.drectve)
   }
-  .idata BLOCK(__section_alignment__) :
+  .stab ALIGN(__section_alignment__) (NOLOAD) :
+  {
+    [ .stab ]
+  }
+  .stabstr ALIGN(__section_alignment__) (NOLOAD) :
+  {
+    [ .stabstr ]
+  }
+  /* DWARF 1.1 and DWARF 2 */
+  .debug_aranges  ALIGN(__section_alignment__) (NOLOAD) : { *(.debug_aranges) }
+  .debug_pubnames ALIGN(__section_alignment__) (NOLOAD) : { *(.debug_pubnames) }
+  /* DWARF 2 */
+  .debug_info     ALIGN(__section_alignment__) (NOLOAD) : { *(.debug_info) }
+  .debug_abbrev   ALIGN(__section_alignment__) (NOLOAD) : { *(.debug_abbrev) }
+  .debug_line     ALIGN(__section_alignment__) (NOLOAD) : { *(.debug_line) }
+  .debug_frame    ALIGN(__section_alignment__) (NOLOAD) : { *(.debug_frame) }
+  .debug_str      ALIGN(__section_alignment__) (NOLOAD) : { *(.debug_str) }
+  .debug_loc      ALIGN(__section_alignment__) (NOLOAD) : { *(.debug_loc) }
+  .debug_macinfo  ALIGN(__section_alignment__) (NOLOAD) : { *(.debug_macinfo) }
+  .debug_macinfo  ALIGN(__section_alignment__) (NOLOAD) : { *(.debug_macinfo) }
+  .debug_ranges   ALIGN(__section_alignment__) (NOLOAD) : { *(.debug_ranges) }
+  .idata ALIGN(__section_alignment__) :
   {
     /* This cannot currently be handled with grouped sections.
        See pe.em:sort_sections.  */
@@ -74,51 +97,17 @@ SECTIONS
     SORT(*)(.idata$5)
     SORT(*)(.idata$6)
     SORT(*)(.idata$7)
+    . = ALIGN(16);
+    __cygheap_start = ABSOLUTE(.);
   }
-  .CRT BLOCK(__section_alignment__) :
-  {
-    *(SORT(.CRT$*))
-  }
-  .endjunk BLOCK(__section_alignment__) :
-  {
-    /* end is deprecated, don't use it */
-     end = .;
-     _end = .;
-     __end__ = .;
-  }
-  .rsrc BLOCK(__section_alignment__) :
-  {
-    *(.rsrc)
-    *(SORT(.rsrc$*))
-  }
-  .reloc BLOCK(__section_alignment__) :
-  {
-    *(.reloc)
-  }
-  .stab BLOCK(__section_alignment__) (NOLOAD) :
-  {
-    [ .stab ]
-  }
-  .stabstr BLOCK(__section_alignment__) (NOLOAD) :
-  {
-    [ .stabstr ]
-  }
-  /* DWARF 1.1 and DWARF 2 */
-  .debug_aranges  BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_aranges) }
-  .debug_pubnames BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_pubnames) }
-  /* DWARF 2 */
-  .debug_info     BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_info) }
-  .debug_abbrev   BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_abbrev) }
-  .debug_line     BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_line) }
-  .debug_frame    BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_frame) }
-  .debug_str      BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_str) }
-  .debug_loc      BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_loc) }
-  .debug_macinfo  BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_macinfo) }
-  .debug_macinfo  BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_macinfo) }
-  .debug_ranges   BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_ranges) }
-  .cygheap BLOCK(64 * 1024) :
+  osection_alignment = __section_alignment__;
+  __section_alignment__ = 64 * 1024;
+  .cygheap ALIGN(4096):
   {
-    __system_dlls__ = ABSOLUTE(.) ;
-    __cygheap_start = ABSOLUTE(.) ;
+    __cygheap_mid = .;
+    . = ALIGN(512 * 1024, 0x10000);
+    . += 8192;         /* inexplicably needed for alignment on 64K boundary?!? */
+_cygheap_foo = .;
   }
+  __cygheap_end = ABSOLUTE(.);
 }
index 4f643ae..fa407d4 100644 (file)
@@ -1030,7 +1030,7 @@ do_exit (int status)
   if (exit_state < ES_CLOSEALL)
     {
       exit_state = ES_CLOSEALL;
-      close_all_files ();
+      close_all_files (false);
     }
 
   if (exit_state < ES_SIGPROCTERMINATE)
index 24a88ce..db69ed3 100644 (file)
@@ -766,7 +766,7 @@ dtable::vfork_parent_restore ()
   lock ();
 
   fhandler_tty_slave *ctty_on_hold = cygheap->ctty_on_hold;
-  close_all_files ();
+  close_all_files (false);
   fhandler_base **deleteme = fds;
   fds = fds_on_hold;
   fds_on_hold = NULL;
index 343eb8c..9e05238 100644 (file)
@@ -84,7 +84,7 @@ public:
   fhandler_base **add_archetype ();
   void delete_archetype (fhandler_base *);
   friend void dtable_init ();
-  friend void __stdcall close_all_files ();
+  friend void __stdcall close_all_files (bool);
   friend class cygheap_fdmanip;
   friend class cygheap_fdget;
   friend class cygheap_fdnew;
index ff2f315..f0b588f 100644 (file)
@@ -82,7 +82,7 @@ enum query_state {
 class fhandler_base
 {
   friend class dtable;
-  friend void close_all_files ();
+  friend void close_all_files (bool);
 
   struct status_flags
   {
index f2e287c..5ecd3bb 100644 (file)
@@ -81,7 +81,11 @@ fork_copy (PROCESS_INFORMATION &pi, const char *what, ...)
          DWORD done = 0;
          if (here + todo > high)
            todo = high - here;
-         int res = WriteProcessMemory (pi.hProcess, here, here, todo, &done);
+         int res;
+         if (pi.hThread)
+           res = WriteProcessMemory (pi.hProcess, here, here, todo, &done);
+         else
+           res = ReadProcessMemory (pi.hProcess, here, here, todo, &done);
          debug_printf ("child handle %p, low %p, high %p, res %d", pi.hProcess,
                        low, high, res);
          if (!res || todo != done)
@@ -223,18 +227,15 @@ fork_child (HANDLE& hParent, dll *&first_dll, bool& load_dlls)
   if (!load_dlls)
     {
       cygheap->fdtab.fixup_after_fork (hParent);
-      ProtectHandleINH (hParent);
       sync_with_parent ("performed fork fixup", false);
     }
   else
     {
       dlls.load_after_fork (hParent, first_dll);
       cygheap->fdtab.fixup_after_fork (hParent);
-      ProtectHandleINH (hParent);
       sync_with_parent ("loaded dlls", true);
     }
 
-  ForceCloseHandle (hParent);
   (void) ForceCloseHandle1 (fork_info->forker_finished, forker_finished);
 
   _my_tls.fixup_after_fork ();
@@ -276,8 +277,7 @@ slow_pid_reuse (HANDLE h)
 #endif
 
 static int __stdcall
-fork_parent (HANDLE& hParent, dll *&first_dll,
-            bool& load_dlls, void *stack_here, child_info_fork &ch)
+fork_parent (HANDLE&, dll *&first_dll, bool& load_dlls, void *stack_here, child_info_fork &ch)
 {
   HANDLE forker_finished;
   DWORD rc;
@@ -308,16 +308,6 @@ fork_parent (HANDLE& hParent, dll *&first_dll,
   if (cygheap->fdtab.need_fixup_before ())
     c_flags |= CREATE_SUSPENDED;
 
-  /* Create an inheritable handle to pass to the child process.  This will
-     allow the child to duplicate handles from the parent to itself. */
-  hParent = NULL;
-  if (!DuplicateHandle (hMainProc, hMainProc, hMainProc, &hParent, 0, TRUE,
-                       DUPLICATE_SAME_ACCESS))
-    {
-      system_printf ("couldn't create handle to myself for child, %E");
-      return -1;
-    }
-
   /* Remember the address of the first loaded dll and decide
      if we need to load dlls.  We do this here so that this
      information will be available in the parent and, when
@@ -331,7 +321,6 @@ fork_parent (HANDLE& hParent, dll *&first_dll,
   forker_finished = CreateEvent (&sec_all, FALSE, FALSE, NULL);
   if (forker_finished == NULL)
     {
-      CloseHandle (hParent);
       system_printf ("unable to allocate forker_finished event, %E");
       return -1;
     }
@@ -349,13 +338,9 @@ fork_parent (HANDLE& hParent, dll *&first_dll,
   /* Remove impersonation */
   cygheap->user.deimpersonate ();
 
-  ch.parent = hParent;
-
   syscall_printf ("CreateProcess (%s, %s, 0, 0, 1, %x, 0, 0, %p, %p)",
                  myself->progname, myself->progname, c_flags, &si, &pi);
   bool locked = __malloc_lock ();
-  void *newheap;
-  newheap = cygheap_setup_for_child (&ch, cygheap->fdtab.need_fixup_before ());
   rc = CreateProcess (myself->progname, /* image to run */
                      myself->progname, /* what we send in arg0 */
                      &sec_none_nih,
@@ -367,8 +352,6 @@ fork_parent (HANDLE& hParent, dll *&first_dll,
                      &si,
                      &pi);
 
-  CloseHandle (hParent);
-
   if (!rc)
     {
       __seterrno ();
@@ -376,19 +359,15 @@ fork_parent (HANDLE& hParent, dll *&first_dll,
       ForceCloseHandle (forker_finished);
       /* Restore impersonation */
       cygheap->user.reimpersonate ();
-      cygheap_setup_for_child_cleanup (newheap, &ch, 0);
       __malloc_unlock ();
       return -1;
     }
 
   /* Fixup the parent datastructure if needed and resume the child's
      main thread. */
-  if (!cygheap->fdtab.need_fixup_before ())
-    cygheap_setup_for_child_cleanup (newheap, &ch, 0);
-  else
+  if (cygheap->fdtab.need_fixup_before ())
     {
       cygheap->fdtab.fixup_before_fork (pi.dwProcessId);
-      cygheap_setup_for_child_cleanup (newheap, &ch, 1);
       ResumeThread (pi.hThread);
     }
 
@@ -542,15 +521,15 @@ fork ()
 {
   struct
   {
-    HANDLE hParent;
     dll *first_dll;
     bool load_dlls;
+    child_info_fork ch;
   } grouped;
 
   MALLOC_CHECK;
 
   debug_printf ("entering");
-  grouped.hParent = grouped.first_dll = NULL;
+  grouped.first_dll = NULL;
   grouped.load_dlls = 0;
 
   void *esp;
@@ -558,19 +537,20 @@ fork ()
 
   myself->set_has_pgid_children ();
 
-  child_info_fork ch;
-  if (ch.subproc_ready == NULL)
+  if (grouped.ch.parent == NULL)
+    return -1;
+  if (grouped.ch.subproc_ready == NULL)
     {
       system_printf ("unable to allocate subproc_ready event, %E");
       return -1;
     }
 
   sig_send (NULL, __SIGHOLD);
-  int res = setjmp (ch.jmp);
+  int res = setjmp (grouped.ch.jmp);
   if (res)
-    res = fork_child (grouped.hParent, grouped.first_dll, grouped.load_dlls);
+    res = fork_child (grouped.ch.parent, grouped.first_dll, grouped.load_dlls);
   else
-    res = fork_parent (grouped.hParent, grouped.first_dll, grouped.load_dlls, esp, ch);
+    res = fork_parent (grouped.ch.parent, grouped.first_dll, grouped.load_dlls, esp, grouped.ch);
   sig_send (NULL, __SIGNOHOLD);
 
   MALLOC_CHECK;
@@ -664,3 +644,14 @@ vfork ()
   return pid;
 #endif
 }
+
+int
+child_copy (HANDLE h, DWORD pid, const char *what, void *child_start, void *child_end)
+{
+  PROCESS_INFORMATION pi;
+  pi.hProcess = h;
+  pi.dwProcessId = pid;
+  pi.hThread = NULL;
+  debug_printf ("%s, start %p, end %p", what, child_start, child_end);
+  return fork_copy (pi, what, child_start, child_end, NULL);
+}
index e12c180..46ef79e 100644 (file)
@@ -737,12 +737,23 @@ child_info::child_info (unsigned in_cb, child_info_types chtype)
   if (chtype != PROC_SPAWN)
     subproc_ready = CreateEvent (&sec_all, FALSE, FALSE, NULL);
   sigproc_printf ("subproc_ready %p", subproc_ready);
+  cygheap = ::cygheap;
+  cygheap_max = ::cygheap_max;
+  dwProcessId = myself->dwProcessId;
+  /* Create an inheritable handle to pass to the child process.  This will
+     allow the child to duplicate handles from the parent to itself. */
+  parent = NULL;
+  if (!DuplicateHandle (hMainProc, hMainProc, hMainProc, &parent, 0, TRUE,
+                       DUPLICATE_SAME_ACCESS))
+    system_printf ("couldn't create handle to myself for child, %E");
 }
 
 child_info::~child_info ()
 {
   if (subproc_ready)
     CloseHandle (subproc_ready);
+  if (parent)
+    CloseHandle (parent);
 }
 
 child_info_fork::child_info_fork () :
index 9faec77..db8b4d9 100644 (file)
@@ -390,12 +390,8 @@ spawn_guts (const char * prog_arg, const char *const *argv,
   else
     chtype = PROC_EXEC;
 
-  child_info_spawn ciresrv (chtype);
-  si.lpReserved2 = (LPBYTE) &ciresrv;
-  si.cbReserved2 = sizeof (ciresrv);
-
-  ciresrv.moreinfo = (cygheap_exec_info *) ccalloc (HEAP_1_EXEC, 1, sizeof (cygheap_exec_info));
-  ciresrv.moreinfo->old_title = NULL;
+  cygheap_exec_info *moreinfo = (cygheap_exec_info *) ccalloc (HEAP_1_EXEC, 1, sizeof (cygheap_exec_info));
+  moreinfo->old_title = NULL;
 
   /* CreateProcess takes one long string that is the command line (sigh).
      We need to quote any argument that has whitespace or embedded "'s.  */
@@ -600,16 +596,16 @@ spawn_guts (const char * prog_arg, const char *const *argv,
       return -1;
     }
 
-  ciresrv.moreinfo->argc = newargv.argc;
-  ciresrv.moreinfo->argv = newargv;
+  moreinfo->argc = newargv.argc;
+  moreinfo->argv = newargv;
 
   if (mode != _P_OVERLAY ||
       !DuplicateHandle (hMainProc, myself.shared_handle (), hMainProc,
-                       &ciresrv.moreinfo->myself_pinfo, 0,
+                       &moreinfo->myself_pinfo, 0,
                        TRUE, DUPLICATE_SAME_ACCESS))
-    ciresrv.moreinfo->myself_pinfo = NULL;
+    moreinfo->myself_pinfo = NULL;
   else
-    VerifyHandle (ciresrv.moreinfo->myself_pinfo);
+    VerifyHandle (moreinfo->myself_pinfo);
 
  skip_arg_parsing:
   PROCESS_INFORMATION pi = {NULL, 0, 0, 0};
@@ -665,13 +661,18 @@ spawn_guts (const char * prog_arg, const char *const *argv,
 
   syscall_printf ("null_app_name %d (%s, %.9500s)", null_app_name, runpath, one_line.buf);
 
-  void *newheap;
-
   cygbench ("spawn-guts");
 
   cygheap->fdtab.set_file_pointers_for_exec ();
   cygheap->user.deimpersonate ();
 
+  moreinfo->envp = build_env (envp, envblock, moreinfo->envc, real_path.iscygexec ());
+  child_info_spawn ciresrv (chtype);
+  ciresrv.moreinfo = moreinfo;
+
+  si.lpReserved2 = (LPBYTE) &ciresrv;
+  si.cbReserved2 = sizeof (ciresrv);
+
   /* When ruid != euid we create the new process under the current original
      account and impersonate in child, this way maintaining the different
      effective vs. real ids.
@@ -682,9 +683,6 @@ spawn_guts (const char * prog_arg, const char *const *argv,
          && cygheap->user.saved_gid == cygheap->user.real_gid
          && !cygheap->user.groups.issetgroups ()))
     {
-      ciresrv.moreinfo->envp = build_env (envp, envblock, ciresrv.moreinfo->envc,
-                                         real_path.iscygexec ());
-      newheap = cygheap_setup_for_child (&ciresrv, cygheap->fdtab.need_fixup_before ());
       rc = CreateProcess (runpath,     /* image name - with full path */
                          one_line.buf, /* what was passed to exec */
                          &sec_none_nih,/* process security attrs */
@@ -719,9 +717,6 @@ spawn_guts (const char * prog_arg, const char *const *argv,
       strcat (wstname, dskname);
       si.lpDesktop = wstname;
 
-      ciresrv.moreinfo->envp = build_env (envp, envblock, ciresrv.moreinfo->envc,
-                                         real_path.iscygexec ());
-      newheap = cygheap_setup_for_child (&ciresrv, cygheap->fdtab.need_fixup_before ());
       rc = CreateProcessAsUser (cygheap->user.primary_token (),
                       runpath,         /* image name - with full path */
                       one_line.buf,    /* what was passed to exec */
@@ -758,7 +753,6 @@ spawn_guts (const char * prog_arg, const char *const *argv,
          myself->sendsig = myself->exec_sendsig;
          myself->exec_sendsig = NULL;
        }
-      cygheap_setup_for_child_cleanup (newheap, &ciresrv, 0);
       return -1;
     }
 
@@ -779,13 +773,8 @@ spawn_guts (const char * prog_arg, const char *const *argv,
 
   /* Fixup the parent data structures if needed and resume the child's
      main thread. */
-  if (!cygheap->fdtab.need_fixup_before ())
-    cygheap_setup_for_child_cleanup (newheap, &ciresrv, 0);
-  else
-    {
-      cygheap->fdtab.fixup_before_exec (pi.dwProcessId);
-      cygheap_setup_for_child_cleanup (newheap, &ciresrv, 1);
-    }
+  if (cygheap->fdtab.need_fixup_before ())
+    cygheap->fdtab.fixup_before_exec (pi.dwProcessId);
 
   if (mode != _P_OVERLAY)
     cygpid = cygwin_pid (pi.dwProcessId);
@@ -807,7 +796,7 @@ spawn_guts (const char * prog_arg, const char *const *argv,
       myself.hProcess = hExeced = pi.hProcess;
       strcpy (myself->progname, real_path); // FIXME: race?
       sigproc_printf ("new process name %s", myself->progname);
-      close_all_files ();
+      close_all_files (true);
       /* If wr_proc_pipe doesn't exist then this process was not started by a cygwin
         process.  So, we need to wait around until the process we've just "execed"
         dies.  Use our own wait facility to wait for our own pid to exit (there
index c67bc37..0222820 100644 (file)
@@ -94,7 +94,7 @@ static int __stdcall stat_worker (const char *name, struct __stat64 *buf,
    ensure we don't leave any such files lying around.  */
 
 void __stdcall
-close_all_files ()
+close_all_files (bool keep_table)
 {
   cygheap->fdtab.lock ();
 
@@ -106,7 +106,8 @@ close_all_files ()
        debug_printf ("closing fd %d", i);
 #endif
        fh->close ();
-       cygheap->fdtab.release (i);
+       if (!keep_table)
+         cygheap->fdtab.release (i);
       }
 
   if (cygheap->ctty)
index bbb092e..6145306 100644 (file)
@@ -221,7 +221,7 @@ void uinfo_init (void);
 void events_init (void);
 void events_terminate (void);
 
-void __stdcall close_all_files ();
+void __stdcall close_all_files (bool);
 
 /* Globals that handle initialization of winsock in a child process. */
 extern HANDLE wsock32_handle;
@@ -298,6 +298,7 @@ extern void multiple_cygwin_problem (const char *, unsigned, unsigned);
 
 extern "C" void vklog (int priority, const char *message, va_list ap);
 extern "C" void klog (int priority, const char *message, ...);
+int child_copy (HANDLE, DWORD, const char *, void *, void *);
 
 int symlink_worker (const char *, const char *, bool, bool)
   __attribute__ ((regparm (3)));