* 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.
This commit is contained in:
parent
302cb8165e
commit
ce95c6407e
|
@ -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>
|
2005-05-30 Vaclav Haisman <v.haisman@sh.cvut.cz>
|
||||||
|
|
||||||
* thread.h (List_remove): Make node parameter const. Use simple
|
* thread.h (List_remove): Make node parameter const. Use simple
|
||||||
|
|
|
@ -29,7 +29,7 @@ enum child_info_types
|
||||||
|
|
||||||
#define EXEC_MAGIC_SIZE sizeof(child_info)
|
#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
|
/* NOTE: Do not make gratuitous changes to the names or organization of the
|
||||||
below class. The layout is checksummed to determine compatibility between
|
below class. The layout is checksummed to determine compatibility between
|
||||||
|
@ -48,7 +48,7 @@ public:
|
||||||
init_cygheap *cygheap;
|
init_cygheap *cygheap;
|
||||||
void *cygheap_max;
|
void *cygheap_max;
|
||||||
DWORD cygheap_reserve_sz;
|
DWORD cygheap_reserve_sz;
|
||||||
HANDLE cygheap_h;
|
DWORD dwProcessId;
|
||||||
unsigned fhandler_union_cb;
|
unsigned fhandler_union_cb;
|
||||||
child_info (unsigned, child_info_types);
|
child_info (unsigned, child_info_types);
|
||||||
~child_info ();
|
~child_info ();
|
||||||
|
|
|
@ -22,12 +22,16 @@
|
||||||
#include "heap.h"
|
#include "heap.h"
|
||||||
#include "sync.h"
|
#include "sync.h"
|
||||||
#include "sigproc.h"
|
#include "sigproc.h"
|
||||||
|
#include "pinfo.h"
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
init_cygheap NO_COPY *cygheap;
|
init_cygheap NO_COPY *cygheap;
|
||||||
void NO_COPY *cygheap_max;
|
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 muto cygheap_protect;
|
||||||
static NO_COPY DWORD reserve_sz;
|
|
||||||
|
|
||||||
struct cygheap_entry
|
struct cygheap_entry
|
||||||
{
|
{
|
||||||
|
@ -44,141 +48,20 @@ struct cygheap_entry
|
||||||
#define MVMAP_OPTIONS (FILE_MAP_WRITE)
|
#define MVMAP_OPTIONS (FILE_MAP_WRITE)
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
static void __stdcall _cfree (void *ptr) __attribute__((regparm(1)));
|
static void __stdcall _cfree (void *) __attribute__((regparm(1)));
|
||||||
}
|
static void *__stdcall _csbrk (int);
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Called by fork or spawn to reallocate cygwin heap */
|
/* Called by fork or spawn to reallocate cygwin heap */
|
||||||
void __stdcall
|
void __stdcall
|
||||||
cygheap_fixup_in_child (bool execed)
|
cygheap_fixup_in_child (bool execed)
|
||||||
{
|
{
|
||||||
cygheap = child_proc_info->cygheap;
|
cygheap_max = child_proc_info->cygheap;
|
||||||
cygheap_max = child_proc_info->cygheap_max;
|
cygheap = (init_cygheap *) cygheap_max;
|
||||||
void *addr = !wincap.map_view_of_file_ex_sucks () ? cygheap : NULL;
|
_csbrk ((char *) child_proc_info->cygheap_max - (char *) cygheap);
|
||||||
void *newaddr;
|
child_copy (child_proc_info->parent, child_proc_info->dwProcessId, "cygheap", cygheap, cygheap_max);
|
||||||
|
if (execed)
|
||||||
newaddr = MapViewOfFileEx (child_proc_info->cygheap_h, MVMAP_OPTIONS, 0, 0, 0, addr);
|
CloseHandle (child_proc_info->parent);
|
||||||
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_init ();
|
cygheap_init ();
|
||||||
debug_fixup_after_fork_exec ();
|
debug_fixup_after_fork_exec ();
|
||||||
|
|
||||||
|
@ -222,30 +105,42 @@ init_cygheap::close_ctty ()
|
||||||
#endif
|
#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
|
static void *__stdcall
|
||||||
_csbrk (int sbs)
|
_csbrk (int sbs)
|
||||||
{
|
{
|
||||||
void *prebrk = cygheap_max;
|
void *prebrk = cygheap_max;
|
||||||
void *prebrka = pagetrunc (prebrk);
|
size_t granmask = getshmlba () - 1;
|
||||||
|
char *newbase = nextpage (prebrk);
|
||||||
cygheap_max = (char *) cygheap_max + sbs;
|
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 */;
|
/* nothing to do */;
|
||||||
else if (!VirtualAlloc (prebrk, (DWORD) sbs, MEM_COMMIT, PAGE_READWRITE))
|
else
|
||||||
{
|
{
|
||||||
#ifdef DEBUGGING
|
if (prebrk <= _cygheap_end)
|
||||||
system_printf ("couldn't commit memory for cygwin heap, prebrk %p, size %d, heapsize now %d, max heap size %u, %E",
|
newbase = _cygheap_end;
|
||||||
prebrk, sbs, (char *) cygheap_max - (char *) cygheap,
|
|
||||||
reserve_sz);
|
DWORD adjsbs = allocsize ((char *) cygheap_max - newbase);
|
||||||
#else
|
if (!VirtualAlloc (newbase, adjsbs, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE))
|
||||||
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,
|
MEMORY_BASIC_INFORMATION m;
|
||||||
reserve_sz);
|
if (!VirtualQuery (newbase, &m, sizeof m))
|
||||||
#endif
|
system_printf ("couldn't get memory info, %E");
|
||||||
__seterrno ();
|
somekinda_printf ("Couldn't reserve/commit %d bytes of space for cygwin's heap, %E",
|
||||||
cygheap_max = (char *) cygheap_max - sbs;
|
adjsbs);
|
||||||
return NULL;
|
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;
|
return prebrk;
|
||||||
|
@ -257,7 +152,13 @@ cygheap_init ()
|
||||||
cygheap_protect.init ("cygheap_protect");
|
cygheap_protect.init ("cygheap_protect");
|
||||||
if (!cygheap)
|
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));
|
(void) _csbrk (sizeof (*cygheap));
|
||||||
}
|
}
|
||||||
if (!cygheap->fdtab)
|
if (!cygheap->fdtab)
|
||||||
|
|
|
@ -416,8 +416,6 @@ class cygheap_fdenum : public cygheap_fdmanip
|
||||||
};
|
};
|
||||||
|
|
||||||
class child_info;
|
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);
|
void __stdcall cygheap_fixup_in_child (bool);
|
||||||
extern "C" {
|
extern "C" {
|
||||||
void __stdcall cfree (void *) __attribute__ ((regparm(1)));
|
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)));
|
char *__stdcall cstrdup1 (const char *) __attribute__ ((regparm(1)));
|
||||||
void __stdcall cfree_and_set (char *&, char * = NULL) __attribute__ ((regparm(2)));
|
void __stdcall cfree_and_set (char *&, char * = NULL) __attribute__ ((regparm(2)));
|
||||||
void __stdcall cygheap_init ();
|
void __stdcall cygheap_init ();
|
||||||
extern DWORD _cygheap_start __attribute__((section(".cygheap")));
|
extern char _cygheap_start[] __attribute__((section(".idata")));
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
OUTPUT_FORMAT(pei-i386)
|
OUTPUT_FORMAT(pei-i386)
|
||||||
SEARCH_DIR(/cygnus/i686-pc-cygwin/lib/w32api); SEARCH_DIR(/cygnus/i686-pc-cygwin/lib);
|
|
||||||
ENTRY(_mainCRTStartup)
|
|
||||||
SECTIONS
|
SECTIONS
|
||||||
{
|
{
|
||||||
.text __image_base__ + __section_alignment__ :
|
.text __image_base__ + __section_alignment__ :
|
||||||
|
@ -10,9 +8,9 @@ SECTIONS
|
||||||
*(SORT(.text$*))
|
*(SORT(.text$*))
|
||||||
*(.glue_7t)
|
*(.glue_7t)
|
||||||
*(.glue_7)
|
*(.glue_7)
|
||||||
___CTOR_LIST__ = .; __CTOR_LIST__ = . ;
|
___CTOR_LIST__ = .; __CTOR_LIST__ = .;
|
||||||
LONG (-1); *(SORT(.ctors.*)); *(.ctors); *(.ctor); LONG (0);
|
LONG (-1); *(SORT(.ctors.*)); *(.ctors); *(.ctor); LONG (0);
|
||||||
___DTOR_LIST__ = .; __DTOR_LIST__ = . ;
|
___DTOR_LIST__ = .; __DTOR_LIST__ = .;
|
||||||
LONG (-1); *(SORT(.dtors.*)); *(.dtors); *(.dtor); LONG (0);
|
LONG (-1); *(SORT(.dtors.*)); *(.dtors); *(.dtor); LONG (0);
|
||||||
*(.fini)
|
*(.fini)
|
||||||
/* ??? Why is .gcc_exc here? */
|
/* ??? Why is .gcc_exc here? */
|
||||||
|
@ -20,38 +18,42 @@ SECTIONS
|
||||||
etext = .;
|
etext = .;
|
||||||
*(.gcc_except_table)
|
*(.gcc_except_table)
|
||||||
}
|
}
|
||||||
|
.autoload_text ALIGN(__section_alignment__) :
|
||||||
|
{
|
||||||
|
*(.*_text);
|
||||||
|
}
|
||||||
/* The Cygwin DLL uses a section to avoid copying certain data
|
/* The Cygwin DLL uses a section to avoid copying certain data
|
||||||
on fork. This used to be named ".data". The linker used
|
on fork. This used to be named ".data". The linker used
|
||||||
to include this between __data_start__ and __data_end__, but that
|
to include this between __data_start__ and __data_end__, but that
|
||||||
breaks building the cygwin32 dll. Instead, we name the section
|
breaks building the cygwin32 dll. Instead, we name the section
|
||||||
".data_cygwin_nocopy" and explictly include it after __data_end__. */
|
".data_cygwin_nocopy" and explictly include it after __data_end__. */
|
||||||
.data BLOCK(__section_alignment__) :
|
.data ALIGN(__section_alignment__) :
|
||||||
{
|
{
|
||||||
__data_start__ = . ;
|
__data_start__ = .;
|
||||||
*(.data)
|
*(.data)
|
||||||
*(.data2)
|
*(.data2)
|
||||||
*(SORT(.data$*))
|
*(SORT(.data$*))
|
||||||
__data_end__ = . ;
|
__data_end__ = .;
|
||||||
*(.data_cygwin_nocopy)
|
*(.data_cygwin_nocopy)
|
||||||
}
|
}
|
||||||
.rdata BLOCK(__section_alignment__) :
|
.rdata ALIGN(__section_alignment__) :
|
||||||
{
|
{
|
||||||
*(.rdata)
|
*(.rdata)
|
||||||
*(SORT(.rdata$*))
|
*(SORT(.rdata$*))
|
||||||
*(.eh_frame)
|
*(.eh_frame)
|
||||||
}
|
}
|
||||||
.pdata BLOCK(__section_alignment__) :
|
.pdata ALIGN(__section_alignment__) :
|
||||||
{
|
{
|
||||||
*(.pdata)
|
*(.pdata)
|
||||||
}
|
}
|
||||||
.bss BLOCK(__section_alignment__) :
|
.bss ALIGN(__section_alignment__) :
|
||||||
{
|
{
|
||||||
__bss_start__ = . ;
|
__bss_start__ = .;
|
||||||
*(.bss)
|
*(.bss)
|
||||||
*(COMMON)
|
*(COMMON)
|
||||||
__bss_end__ = . ;
|
__bss_end__ = .;
|
||||||
}
|
}
|
||||||
.edata BLOCK(__section_alignment__) :
|
.edata ALIGN(__section_alignment__) :
|
||||||
{
|
{
|
||||||
*(.edata)
|
*(.edata)
|
||||||
}
|
}
|
||||||
|
@ -62,7 +64,28 @@ SECTIONS
|
||||||
*(.debug$F)
|
*(.debug$F)
|
||||||
*(.drectve)
|
*(.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.
|
/* This cannot currently be handled with grouped sections.
|
||||||
See pe.em:sort_sections. */
|
See pe.em:sort_sections. */
|
||||||
|
@ -74,51 +97,17 @@ SECTIONS
|
||||||
SORT(*)(.idata$5)
|
SORT(*)(.idata$5)
|
||||||
SORT(*)(.idata$6)
|
SORT(*)(.idata$6)
|
||||||
SORT(*)(.idata$7)
|
SORT(*)(.idata$7)
|
||||||
|
. = ALIGN(16);
|
||||||
|
__cygheap_start = ABSOLUTE(.);
|
||||||
}
|
}
|
||||||
.CRT BLOCK(__section_alignment__) :
|
osection_alignment = __section_alignment__;
|
||||||
|
__section_alignment__ = 64 * 1024;
|
||||||
|
.cygheap ALIGN(4096):
|
||||||
{
|
{
|
||||||
*(SORT(.CRT$*))
|
__cygheap_mid = .;
|
||||||
}
|
. = ALIGN(512 * 1024, 0x10000);
|
||||||
.endjunk BLOCK(__section_alignment__) :
|
. += 8192; /* inexplicably needed for alignment on 64K boundary?!? */
|
||||||
{
|
_cygheap_foo = .;
|
||||||
/* 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) :
|
|
||||||
{
|
|
||||||
__system_dlls__ = ABSOLUTE(.) ;
|
|
||||||
__cygheap_start = ABSOLUTE(.) ;
|
|
||||||
}
|
}
|
||||||
|
__cygheap_end = ABSOLUTE(.);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1030,7 +1030,7 @@ do_exit (int status)
|
||||||
if (exit_state < ES_CLOSEALL)
|
if (exit_state < ES_CLOSEALL)
|
||||||
{
|
{
|
||||||
exit_state = ES_CLOSEALL;
|
exit_state = ES_CLOSEALL;
|
||||||
close_all_files ();
|
close_all_files (false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (exit_state < ES_SIGPROCTERMINATE)
|
if (exit_state < ES_SIGPROCTERMINATE)
|
||||||
|
|
|
@ -766,7 +766,7 @@ dtable::vfork_parent_restore ()
|
||||||
lock ();
|
lock ();
|
||||||
|
|
||||||
fhandler_tty_slave *ctty_on_hold = cygheap->ctty_on_hold;
|
fhandler_tty_slave *ctty_on_hold = cygheap->ctty_on_hold;
|
||||||
close_all_files ();
|
close_all_files (false);
|
||||||
fhandler_base **deleteme = fds;
|
fhandler_base **deleteme = fds;
|
||||||
fds = fds_on_hold;
|
fds = fds_on_hold;
|
||||||
fds_on_hold = NULL;
|
fds_on_hold = NULL;
|
||||||
|
|
|
@ -84,7 +84,7 @@ public:
|
||||||
fhandler_base **add_archetype ();
|
fhandler_base **add_archetype ();
|
||||||
void delete_archetype (fhandler_base *);
|
void delete_archetype (fhandler_base *);
|
||||||
friend void dtable_init ();
|
friend void dtable_init ();
|
||||||
friend void __stdcall close_all_files ();
|
friend void __stdcall close_all_files (bool);
|
||||||
friend class cygheap_fdmanip;
|
friend class cygheap_fdmanip;
|
||||||
friend class cygheap_fdget;
|
friend class cygheap_fdget;
|
||||||
friend class cygheap_fdnew;
|
friend class cygheap_fdnew;
|
||||||
|
|
|
@ -82,7 +82,7 @@ enum query_state {
|
||||||
class fhandler_base
|
class fhandler_base
|
||||||
{
|
{
|
||||||
friend class dtable;
|
friend class dtable;
|
||||||
friend void close_all_files ();
|
friend void close_all_files (bool);
|
||||||
|
|
||||||
struct status_flags
|
struct status_flags
|
||||||
{
|
{
|
||||||
|
|
|
@ -81,7 +81,11 @@ fork_copy (PROCESS_INFORMATION &pi, const char *what, ...)
|
||||||
DWORD done = 0;
|
DWORD done = 0;
|
||||||
if (here + todo > high)
|
if (here + todo > high)
|
||||||
todo = high - here;
|
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,
|
debug_printf ("child handle %p, low %p, high %p, res %d", pi.hProcess,
|
||||||
low, high, res);
|
low, high, res);
|
||||||
if (!res || todo != done)
|
if (!res || todo != done)
|
||||||
|
@ -223,18 +227,15 @@ fork_child (HANDLE& hParent, dll *&first_dll, bool& load_dlls)
|
||||||
if (!load_dlls)
|
if (!load_dlls)
|
||||||
{
|
{
|
||||||
cygheap->fdtab.fixup_after_fork (hParent);
|
cygheap->fdtab.fixup_after_fork (hParent);
|
||||||
ProtectHandleINH (hParent);
|
|
||||||
sync_with_parent ("performed fork fixup", false);
|
sync_with_parent ("performed fork fixup", false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
dlls.load_after_fork (hParent, first_dll);
|
dlls.load_after_fork (hParent, first_dll);
|
||||||
cygheap->fdtab.fixup_after_fork (hParent);
|
cygheap->fdtab.fixup_after_fork (hParent);
|
||||||
ProtectHandleINH (hParent);
|
|
||||||
sync_with_parent ("loaded dlls", true);
|
sync_with_parent ("loaded dlls", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
ForceCloseHandle (hParent);
|
|
||||||
(void) ForceCloseHandle1 (fork_info->forker_finished, forker_finished);
|
(void) ForceCloseHandle1 (fork_info->forker_finished, forker_finished);
|
||||||
|
|
||||||
_my_tls.fixup_after_fork ();
|
_my_tls.fixup_after_fork ();
|
||||||
|
@ -276,8 +277,7 @@ slow_pid_reuse (HANDLE h)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int __stdcall
|
static int __stdcall
|
||||||
fork_parent (HANDLE& hParent, dll *&first_dll,
|
fork_parent (HANDLE&, dll *&first_dll, bool& load_dlls, void *stack_here, child_info_fork &ch)
|
||||||
bool& load_dlls, void *stack_here, child_info_fork &ch)
|
|
||||||
{
|
{
|
||||||
HANDLE forker_finished;
|
HANDLE forker_finished;
|
||||||
DWORD rc;
|
DWORD rc;
|
||||||
|
@ -308,16 +308,6 @@ fork_parent (HANDLE& hParent, dll *&first_dll,
|
||||||
if (cygheap->fdtab.need_fixup_before ())
|
if (cygheap->fdtab.need_fixup_before ())
|
||||||
c_flags |= CREATE_SUSPENDED;
|
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
|
/* Remember the address of the first loaded dll and decide
|
||||||
if we need to load dlls. We do this here so that this
|
if we need to load dlls. We do this here so that this
|
||||||
information will be available in the parent and, when
|
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);
|
forker_finished = CreateEvent (&sec_all, FALSE, FALSE, NULL);
|
||||||
if (forker_finished == NULL)
|
if (forker_finished == NULL)
|
||||||
{
|
{
|
||||||
CloseHandle (hParent);
|
|
||||||
system_printf ("unable to allocate forker_finished event, %E");
|
system_printf ("unable to allocate forker_finished event, %E");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -349,13 +338,9 @@ fork_parent (HANDLE& hParent, dll *&first_dll,
|
||||||
/* Remove impersonation */
|
/* Remove impersonation */
|
||||||
cygheap->user.deimpersonate ();
|
cygheap->user.deimpersonate ();
|
||||||
|
|
||||||
ch.parent = hParent;
|
|
||||||
|
|
||||||
syscall_printf ("CreateProcess (%s, %s, 0, 0, 1, %x, 0, 0, %p, %p)",
|
syscall_printf ("CreateProcess (%s, %s, 0, 0, 1, %x, 0, 0, %p, %p)",
|
||||||
myself->progname, myself->progname, c_flags, &si, &pi);
|
myself->progname, myself->progname, c_flags, &si, &pi);
|
||||||
bool locked = __malloc_lock ();
|
bool locked = __malloc_lock ();
|
||||||
void *newheap;
|
|
||||||
newheap = cygheap_setup_for_child (&ch, cygheap->fdtab.need_fixup_before ());
|
|
||||||
rc = CreateProcess (myself->progname, /* image to run */
|
rc = CreateProcess (myself->progname, /* image to run */
|
||||||
myself->progname, /* what we send in arg0 */
|
myself->progname, /* what we send in arg0 */
|
||||||
&sec_none_nih,
|
&sec_none_nih,
|
||||||
|
@ -367,8 +352,6 @@ fork_parent (HANDLE& hParent, dll *&first_dll,
|
||||||
&si,
|
&si,
|
||||||
&pi);
|
&pi);
|
||||||
|
|
||||||
CloseHandle (hParent);
|
|
||||||
|
|
||||||
if (!rc)
|
if (!rc)
|
||||||
{
|
{
|
||||||
__seterrno ();
|
__seterrno ();
|
||||||
|
@ -376,19 +359,15 @@ fork_parent (HANDLE& hParent, dll *&first_dll,
|
||||||
ForceCloseHandle (forker_finished);
|
ForceCloseHandle (forker_finished);
|
||||||
/* Restore impersonation */
|
/* Restore impersonation */
|
||||||
cygheap->user.reimpersonate ();
|
cygheap->user.reimpersonate ();
|
||||||
cygheap_setup_for_child_cleanup (newheap, &ch, 0);
|
|
||||||
__malloc_unlock ();
|
__malloc_unlock ();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fixup the parent datastructure if needed and resume the child's
|
/* Fixup the parent datastructure if needed and resume the child's
|
||||||
main thread. */
|
main thread. */
|
||||||
if (!cygheap->fdtab.need_fixup_before ())
|
if (cygheap->fdtab.need_fixup_before ())
|
||||||
cygheap_setup_for_child_cleanup (newheap, &ch, 0);
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
cygheap->fdtab.fixup_before_fork (pi.dwProcessId);
|
cygheap->fdtab.fixup_before_fork (pi.dwProcessId);
|
||||||
cygheap_setup_for_child_cleanup (newheap, &ch, 1);
|
|
||||||
ResumeThread (pi.hThread);
|
ResumeThread (pi.hThread);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -542,15 +521,15 @@ fork ()
|
||||||
{
|
{
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
HANDLE hParent;
|
|
||||||
dll *first_dll;
|
dll *first_dll;
|
||||||
bool load_dlls;
|
bool load_dlls;
|
||||||
|
child_info_fork ch;
|
||||||
} grouped;
|
} grouped;
|
||||||
|
|
||||||
MALLOC_CHECK;
|
MALLOC_CHECK;
|
||||||
|
|
||||||
debug_printf ("entering");
|
debug_printf ("entering");
|
||||||
grouped.hParent = grouped.first_dll = NULL;
|
grouped.first_dll = NULL;
|
||||||
grouped.load_dlls = 0;
|
grouped.load_dlls = 0;
|
||||||
|
|
||||||
void *esp;
|
void *esp;
|
||||||
|
@ -558,19 +537,20 @@ fork ()
|
||||||
|
|
||||||
myself->set_has_pgid_children ();
|
myself->set_has_pgid_children ();
|
||||||
|
|
||||||
child_info_fork ch;
|
if (grouped.ch.parent == NULL)
|
||||||
if (ch.subproc_ready == NULL)
|
return -1;
|
||||||
|
if (grouped.ch.subproc_ready == NULL)
|
||||||
{
|
{
|
||||||
system_printf ("unable to allocate subproc_ready event, %E");
|
system_printf ("unable to allocate subproc_ready event, %E");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
sig_send (NULL, __SIGHOLD);
|
sig_send (NULL, __SIGHOLD);
|
||||||
int res = setjmp (ch.jmp);
|
int res = setjmp (grouped.ch.jmp);
|
||||||
if (res)
|
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
|
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);
|
sig_send (NULL, __SIGNOHOLD);
|
||||||
|
|
||||||
MALLOC_CHECK;
|
MALLOC_CHECK;
|
||||||
|
@ -664,3 +644,14 @@ vfork ()
|
||||||
return pid;
|
return pid;
|
||||||
#endif
|
#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);
|
||||||
|
}
|
||||||
|
|
|
@ -737,12 +737,23 @@ child_info::child_info (unsigned in_cb, child_info_types chtype)
|
||||||
if (chtype != PROC_SPAWN)
|
if (chtype != PROC_SPAWN)
|
||||||
subproc_ready = CreateEvent (&sec_all, FALSE, FALSE, NULL);
|
subproc_ready = CreateEvent (&sec_all, FALSE, FALSE, NULL);
|
||||||
sigproc_printf ("subproc_ready %p", subproc_ready);
|
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 ()
|
child_info::~child_info ()
|
||||||
{
|
{
|
||||||
if (subproc_ready)
|
if (subproc_ready)
|
||||||
CloseHandle (subproc_ready);
|
CloseHandle (subproc_ready);
|
||||||
|
if (parent)
|
||||||
|
CloseHandle (parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
child_info_fork::child_info_fork () :
|
child_info_fork::child_info_fork () :
|
||||||
|
|
|
@ -390,12 +390,8 @@ spawn_guts (const char * prog_arg, const char *const *argv,
|
||||||
else
|
else
|
||||||
chtype = PROC_EXEC;
|
chtype = PROC_EXEC;
|
||||||
|
|
||||||
child_info_spawn ciresrv (chtype);
|
cygheap_exec_info *moreinfo = (cygheap_exec_info *) ccalloc (HEAP_1_EXEC, 1, sizeof (cygheap_exec_info));
|
||||||
si.lpReserved2 = (LPBYTE) &ciresrv;
|
moreinfo->old_title = NULL;
|
||||||
si.cbReserved2 = sizeof (ciresrv);
|
|
||||||
|
|
||||||
ciresrv.moreinfo = (cygheap_exec_info *) ccalloc (HEAP_1_EXEC, 1, sizeof (cygheap_exec_info));
|
|
||||||
ciresrv.moreinfo->old_title = NULL;
|
|
||||||
|
|
||||||
/* CreateProcess takes one long string that is the command line (sigh).
|
/* CreateProcess takes one long string that is the command line (sigh).
|
||||||
We need to quote any argument that has whitespace or embedded "'s. */
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ciresrv.moreinfo->argc = newargv.argc;
|
moreinfo->argc = newargv.argc;
|
||||||
ciresrv.moreinfo->argv = newargv;
|
moreinfo->argv = newargv;
|
||||||
|
|
||||||
if (mode != _P_OVERLAY ||
|
if (mode != _P_OVERLAY ||
|
||||||
!DuplicateHandle (hMainProc, myself.shared_handle (), hMainProc,
|
!DuplicateHandle (hMainProc, myself.shared_handle (), hMainProc,
|
||||||
&ciresrv.moreinfo->myself_pinfo, 0,
|
&moreinfo->myself_pinfo, 0,
|
||||||
TRUE, DUPLICATE_SAME_ACCESS))
|
TRUE, DUPLICATE_SAME_ACCESS))
|
||||||
ciresrv.moreinfo->myself_pinfo = NULL;
|
moreinfo->myself_pinfo = NULL;
|
||||||
else
|
else
|
||||||
VerifyHandle (ciresrv.moreinfo->myself_pinfo);
|
VerifyHandle (moreinfo->myself_pinfo);
|
||||||
|
|
||||||
skip_arg_parsing:
|
skip_arg_parsing:
|
||||||
PROCESS_INFORMATION pi = {NULL, 0, 0, 0};
|
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);
|
syscall_printf ("null_app_name %d (%s, %.9500s)", null_app_name, runpath, one_line.buf);
|
||||||
|
|
||||||
void *newheap;
|
|
||||||
|
|
||||||
cygbench ("spawn-guts");
|
cygbench ("spawn-guts");
|
||||||
|
|
||||||
cygheap->fdtab.set_file_pointers_for_exec ();
|
cygheap->fdtab.set_file_pointers_for_exec ();
|
||||||
cygheap->user.deimpersonate ();
|
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
|
/* When ruid != euid we create the new process under the current original
|
||||||
account and impersonate in child, this way maintaining the different
|
account and impersonate in child, this way maintaining the different
|
||||||
effective vs. real ids.
|
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.saved_gid == cygheap->user.real_gid
|
||||||
&& !cygheap->user.groups.issetgroups ()))
|
&& !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 */
|
rc = CreateProcess (runpath, /* image name - with full path */
|
||||||
one_line.buf, /* what was passed to exec */
|
one_line.buf, /* what was passed to exec */
|
||||||
&sec_none_nih,/* process security attrs */
|
&sec_none_nih,/* process security attrs */
|
||||||
|
@ -719,9 +717,6 @@ spawn_guts (const char * prog_arg, const char *const *argv,
|
||||||
strcat (wstname, dskname);
|
strcat (wstname, dskname);
|
||||||
si.lpDesktop = wstname;
|
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 (),
|
rc = CreateProcessAsUser (cygheap->user.primary_token (),
|
||||||
runpath, /* image name - with full path */
|
runpath, /* image name - with full path */
|
||||||
one_line.buf, /* what was passed to exec */
|
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->sendsig = myself->exec_sendsig;
|
||||||
myself->exec_sendsig = NULL;
|
myself->exec_sendsig = NULL;
|
||||||
}
|
}
|
||||||
cygheap_setup_for_child_cleanup (newheap, &ciresrv, 0);
|
|
||||||
return -1;
|
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
|
/* Fixup the parent data structures if needed and resume the child's
|
||||||
main thread. */
|
main thread. */
|
||||||
if (!cygheap->fdtab.need_fixup_before ())
|
if (cygheap->fdtab.need_fixup_before ())
|
||||||
cygheap_setup_for_child_cleanup (newheap, &ciresrv, 0);
|
cygheap->fdtab.fixup_before_exec (pi.dwProcessId);
|
||||||
else
|
|
||||||
{
|
|
||||||
cygheap->fdtab.fixup_before_exec (pi.dwProcessId);
|
|
||||||
cygheap_setup_for_child_cleanup (newheap, &ciresrv, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mode != _P_OVERLAY)
|
if (mode != _P_OVERLAY)
|
||||||
cygpid = cygwin_pid (pi.dwProcessId);
|
cygpid = cygwin_pid (pi.dwProcessId);
|
||||||
|
@ -807,7 +796,7 @@ spawn_guts (const char * prog_arg, const char *const *argv,
|
||||||
myself.hProcess = hExeced = pi.hProcess;
|
myself.hProcess = hExeced = pi.hProcess;
|
||||||
strcpy (myself->progname, real_path); // FIXME: race?
|
strcpy (myself->progname, real_path); // FIXME: race?
|
||||||
sigproc_printf ("new process name %s", myself->progname);
|
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
|
/* 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"
|
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
|
dies. Use our own wait facility to wait for our own pid to exit (there
|
||||||
|
|
|
@ -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. */
|
ensure we don't leave any such files lying around. */
|
||||||
|
|
||||||
void __stdcall
|
void __stdcall
|
||||||
close_all_files ()
|
close_all_files (bool keep_table)
|
||||||
{
|
{
|
||||||
cygheap->fdtab.lock ();
|
cygheap->fdtab.lock ();
|
||||||
|
|
||||||
|
@ -106,7 +106,8 @@ close_all_files ()
|
||||||
debug_printf ("closing fd %d", i);
|
debug_printf ("closing fd %d", i);
|
||||||
#endif
|
#endif
|
||||||
fh->close ();
|
fh->close ();
|
||||||
cygheap->fdtab.release (i);
|
if (!keep_table)
|
||||||
|
cygheap->fdtab.release (i);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cygheap->ctty)
|
if (cygheap->ctty)
|
||||||
|
|
|
@ -221,7 +221,7 @@ void uinfo_init (void);
|
||||||
void events_init (void);
|
void events_init (void);
|
||||||
void events_terminate (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. */
|
/* Globals that handle initialization of winsock in a child process. */
|
||||||
extern HANDLE wsock32_handle;
|
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 vklog (int priority, const char *message, va_list ap);
|
||||||
extern "C" void klog (int priority, const char *message, ...);
|
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)
|
int symlink_worker (const char *, const char *, bool, bool)
|
||||||
__attribute__ ((regparm (3)));
|
__attribute__ ((regparm (3)));
|
||||||
|
|
Loading…
Reference in New Issue