mirror of
git://sourceware.org/git/newlib-cygwin.git
synced 2025-01-20 05:19:21 +08:00
* cygheap.cc (cygheap_fixup_in_child): Don't page round cygheap copied from
parent. * dcrt0.cc (do_exit): Don't cleanup pinfo on exit. That happens automatically now. * exceptions.cc (signal_exit): Ditto. * fork.cc (fork_parent): Use stack_here value passed in from fork(). (fork): Figure out top of stack here and pass it to fork_parent. * pinfo.cc (_pinfo::record_death): Eliminate. * pinfo.h (_pinfo): Ditto. * sigproc.cc (proc_exists): Simplify. (proc_terminate): Ditto. (remove_zombie): Don't cleanup pinfo stuff. (wait_sig): Send subproc_ready signal whether execed or spawned. * spawn.cc (spawn_guts): Always create subproc_ready event. Use it for both exec and spawn. (_spawnve): Send proper mode to spawn_guts when mode != _P_OVERLAY.
This commit is contained in:
parent
cbe4c8e234
commit
aece55b982
@ -1,3 +1,22 @@
|
|||||||
|
Sat Oct 14 01:45:25 2000 Christopher Faylor <cgf@cygnus.com>
|
||||||
|
|
||||||
|
* cygheap.cc (cygheap_fixup_in_child): Don't page round cygheap copied
|
||||||
|
from parent.
|
||||||
|
* dcrt0.cc (do_exit): Don't cleanup pinfo on exit. That happens
|
||||||
|
automatically now.
|
||||||
|
* exceptions.cc (signal_exit): Ditto.
|
||||||
|
* fork.cc (fork_parent): Use stack_here value passed in from fork().
|
||||||
|
(fork): Figure out top of stack here and pass it to fork_parent.
|
||||||
|
* pinfo.cc (_pinfo::record_death): Eliminate.
|
||||||
|
* pinfo.h (_pinfo): Ditto.
|
||||||
|
* sigproc.cc (proc_exists): Simplify.
|
||||||
|
(proc_terminate): Ditto.
|
||||||
|
(remove_zombie): Don't cleanup pinfo stuff.
|
||||||
|
(wait_sig): Send subproc_ready signal whether execed or spawned.
|
||||||
|
* spawn.cc (spawn_guts): Always create subproc_ready event. Use it for
|
||||||
|
both exec and spawn.
|
||||||
|
(_spawnve): Send proper mode to spawn_guts when mode != _P_OVERLAY.
|
||||||
|
|
||||||
Thu Oct 12 23:11:05 2000 Christopher Faylor <cgf@cygnus.com>
|
Thu Oct 12 23:11:05 2000 Christopher Faylor <cgf@cygnus.com>
|
||||||
|
|
||||||
* dtable.cc (dtable::fixup_after_fork): Revert thinko below.
|
* dtable.cc (dtable::fixup_after_fork): Revert thinko below.
|
||||||
|
@ -207,9 +207,7 @@ cygheap_fixup_in_child (HANDLE parent, bool execed)
|
|||||||
|
|
||||||
/* Copy memory from the parent */
|
/* Copy memory from the parent */
|
||||||
m = 0;
|
m = 0;
|
||||||
n = (DWORD) pagetrunc (n + 4095);
|
if (!ReadProcessMemory (parent, cygheap, cygheap, n, &m) || m != n)
|
||||||
if (!ReadProcessMemory (parent, cygheap, cygheap, n, &m) ||
|
|
||||||
m != n)
|
|
||||||
api_fatal ("Couldn't read parent's cygwin heap %d bytes != %d, %E",
|
api_fatal ("Couldn't read parent's cygwin heap %d bytes != %d, %E",
|
||||||
n, m);
|
n, m);
|
||||||
|
|
||||||
|
@ -973,7 +973,6 @@ enum
|
|||||||
extern "C" void __stdcall
|
extern "C" void __stdcall
|
||||||
do_exit (int status)
|
do_exit (int status)
|
||||||
{
|
{
|
||||||
BOOL cleanup_pinfo;
|
|
||||||
UINT n = (UINT) status;
|
UINT n = (UINT) status;
|
||||||
static int NO_COPY exit_state = 0;
|
static int NO_COPY exit_state = 0;
|
||||||
|
|
||||||
@ -1013,10 +1012,7 @@ do_exit (int status)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (n & EXIT_REPARENTING)
|
if (n & EXIT_REPARENTING)
|
||||||
{
|
|
||||||
n &= ~EXIT_REPARENTING;
|
n &= ~EXIT_REPARENTING;
|
||||||
cleanup_pinfo = FALSE;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
myself->stopsig = 0;
|
myself->stopsig = 0;
|
||||||
@ -1045,7 +1041,6 @@ do_exit (int status)
|
|||||||
}
|
}
|
||||||
|
|
||||||
tty_terminate ();
|
tty_terminate ();
|
||||||
cleanup_pinfo = TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
window_terminate ();
|
window_terminate ();
|
||||||
@ -1060,11 +1055,6 @@ do_exit (int status)
|
|||||||
ForceCloseHandle1 (hExeced, childhProc);
|
ForceCloseHandle1 (hExeced, childhProc);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cleanup_pinfo)
|
|
||||||
myself->record_death ();
|
|
||||||
else
|
|
||||||
sigproc_printf ("not cleanup_pinfo");
|
|
||||||
|
|
||||||
shared_terminate ();
|
shared_terminate ();
|
||||||
|
|
||||||
sigproc_printf ("calling ExitProcess %d", n);
|
sigproc_printf ("calling ExitProcess %d", n);
|
||||||
@ -1106,7 +1096,6 @@ __api_fatal (const char *fmt, ...)
|
|||||||
/* We are going down without mercy. Make sure we reset
|
/* We are going down without mercy. Make sure we reset
|
||||||
our process_state. */
|
our process_state. */
|
||||||
sigproc_terminate ();
|
sigproc_terminate ();
|
||||||
myself->record_death ();
|
|
||||||
#ifdef DEBUGGING
|
#ifdef DEBUGGING
|
||||||
(void) try_to_debug ();
|
(void) try_to_debug ();
|
||||||
#endif
|
#endif
|
||||||
|
@ -1005,11 +1005,7 @@ signal_exit (int rc)
|
|||||||
{
|
{
|
||||||
rc = EXIT_SIGNAL | (rc << 8);
|
rc = EXIT_SIGNAL | (rc << 8);
|
||||||
if (exit_already++)
|
if (exit_already++)
|
||||||
{
|
|
||||||
/* We are going down - reset our process_state without locking. */
|
|
||||||
myself->record_death ();
|
|
||||||
ExitProcess (rc);
|
ExitProcess (rc);
|
||||||
}
|
|
||||||
|
|
||||||
/* We'd like to stop the main thread from executing but when we do that it
|
/* We'd like to stop the main thread from executing but when we do that it
|
||||||
causes random, inexplicable hangs. So, instead, we set up the priority
|
causes random, inexplicable hangs. So, instead, we set up the priority
|
||||||
|
@ -308,10 +308,9 @@ debug_printf ("hParent %p", hParent);
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int __stdcall
|
static int __stdcall
|
||||||
fork_parent (HANDLE& hParent, dll *&first_dll, bool& load_dlls, child_info_fork &ch)
|
fork_parent (void *stack_here, HANDLE& hParent, dll *&first_dll, bool& load_dlls, child_info_fork &ch)
|
||||||
{
|
{
|
||||||
HANDLE subproc_ready, forker_finished;
|
HANDLE subproc_ready, forker_finished;
|
||||||
void *stack_here = &hParent;
|
|
||||||
DWORD rc;
|
DWORD rc;
|
||||||
PROCESS_INFORMATION pi = {0, NULL, 0, 0};
|
PROCESS_INFORMATION pi = {0, NULL, 0, 0};
|
||||||
static NO_COPY HANDLE last_fork_proc = NULL;
|
static NO_COPY HANDLE last_fork_proc = NULL;
|
||||||
@ -339,8 +338,6 @@ fork_parent (HANDLE& hParent, dll *&first_dll, bool& load_dlls, child_info_fork
|
|||||||
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
|
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
syscall_printf ("CreateProcessA (%s, %s,0,0,1,%x, 0,0,%p,%p)",
|
|
||||||
myself->progname, myself->progname, c_flags, &si, &pi);
|
|
||||||
if (console_handle != INVALID_HANDLE_VALUE && console_handle != 0)
|
if (console_handle != INVALID_HANDLE_VALUE && console_handle != 0)
|
||||||
CloseHandle (console_handle);
|
CloseHandle (console_handle);
|
||||||
else
|
else
|
||||||
@ -407,7 +404,9 @@ fork_parent (HANDLE& hParent, dll *&first_dll, bool& load_dlls, child_info_fork
|
|||||||
ch.cygheap_max = cygheap_max;
|
ch.cygheap_max = cygheap_max;
|
||||||
|
|
||||||
char sa_buf[1024];
|
char sa_buf[1024];
|
||||||
rc = CreateProcessA (myself->progname, /* image to run */
|
syscall_printf ("CreateProcess (%s, %s, 0, 0, 1, %x, 0, 0, %p, %p)",
|
||||||
|
myself->progname, myself->progname, c_flags, &si, &pi);
|
||||||
|
rc = CreateProcess (myself->progname, /* image to run */
|
||||||
myself->progname, /* what we send in arg0 */
|
myself->progname, /* what we send in arg0 */
|
||||||
allow_ntsec ? sec_user (sa_buf) : &sec_none_nih,
|
allow_ntsec ? sec_user (sa_buf) : &sec_none_nih,
|
||||||
allow_ntsec ? sec_user (sa_buf) : &sec_none_nih,
|
allow_ntsec ? sec_user (sa_buf) : &sec_none_nih,
|
||||||
@ -579,14 +578,11 @@ fork ()
|
|||||||
bool load_dlls;
|
bool load_dlls;
|
||||||
} grouped;
|
} grouped;
|
||||||
|
|
||||||
int res;
|
|
||||||
int x;
|
|
||||||
|
|
||||||
MALLOC_CHECK;
|
MALLOC_CHECK;
|
||||||
|
|
||||||
// grow_stack_slack ();
|
|
||||||
|
|
||||||
debug_printf ("entering");
|
debug_printf ("entering");
|
||||||
|
grouped.hParent = grouped.first_dll = NULL;
|
||||||
|
grouped.load_dlls = 0;
|
||||||
|
|
||||||
if (ISSTATE(myself, PID_SPLIT_HEAP))
|
if (ISSTATE(myself, PID_SPLIT_HEAP))
|
||||||
{
|
{
|
||||||
@ -597,13 +593,17 @@ fork ()
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
child_info_fork ch;
|
void *esp;
|
||||||
x = setjmp (ch.jmp);
|
__asm ("movl %%esp,%0": "=r" (esp));
|
||||||
|
|
||||||
if (x != 0)
|
child_info_fork ch;
|
||||||
|
|
||||||
|
int res = setjmp (ch.jmp);
|
||||||
|
|
||||||
|
if (res)
|
||||||
res = fork_child (grouped.hParent, grouped.first_dll, grouped.load_dlls);
|
res = fork_child (grouped.hParent, grouped.first_dll, grouped.load_dlls);
|
||||||
else
|
else
|
||||||
res = fork_parent (grouped.hParent, grouped.first_dll, grouped.load_dlls, ch);
|
res = fork_parent (esp, grouped.hParent, grouped.first_dll, grouped.load_dlls, ch);
|
||||||
|
|
||||||
MALLOC_CHECK;
|
MALLOC_CHECK;
|
||||||
syscall_printf ("%d = fork()", res);
|
syscall_printf ("%d = fork()", res);
|
||||||
|
@ -174,17 +174,6 @@ _pinfo::copysigs(_pinfo *_other)
|
|||||||
sigs = _other->sigs;
|
sigs = _other->sigs;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
_pinfo::record_death ()
|
|
||||||
{
|
|
||||||
/* CGF FIXME - needed? */
|
|
||||||
if (dwProcessId == GetCurrentProcessId () && !my_parent_is_alive ())
|
|
||||||
{
|
|
||||||
process_state = PID_NOT_IN_USE;
|
|
||||||
hProcess = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
pinfo::init (pid_t n, DWORD create, HANDLE in_h)
|
pinfo::init (pid_t n, DWORD create, HANDLE in_h)
|
||||||
{
|
{
|
||||||
|
@ -119,8 +119,6 @@ private:
|
|||||||
public:
|
public:
|
||||||
/* Pointer to mmap'ed areas for this process. Set up by fork. */
|
/* Pointer to mmap'ed areas for this process. Set up by fork. */
|
||||||
void *mmap_ptr;
|
void *mmap_ptr;
|
||||||
|
|
||||||
void record_death ();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class pinfo
|
class pinfo
|
||||||
|
@ -205,48 +205,8 @@ proc_exists (_pinfo *p)
|
|||||||
|
|
||||||
if (p == NULL)
|
if (p == NULL)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
else
|
||||||
if (p == myself || p == myself_nowait_nonmain || p == myself_nowait)
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
if (p->process_state == PID_NOT_IN_USE || !p->dwProcessId)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
sigproc_printf ("checking for existence of pid %d, window pid %d", p->pid,
|
|
||||||
p->dwProcessId);
|
|
||||||
if (p->ppid == myself->pid && p->hProcess != NULL)
|
|
||||||
{
|
|
||||||
sigproc_printf ("it's mine, process_state %x", p->process_state);
|
|
||||||
return proc_can_be_signalled (p);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Note: Process is alive if OpenProcess() call fails due to permissions */
|
|
||||||
if (((h = OpenProcess (STANDARD_RIGHTS_REQUIRED, FALSE, p->dwProcessId))
|
|
||||||
!= NULL) || (GetLastError () == ERROR_ACCESS_DENIED))
|
|
||||||
{
|
|
||||||
sigproc_printf ("it exists, %p", h);
|
|
||||||
if (h)
|
|
||||||
{
|
|
||||||
DWORD rc = WaitForSingleObject (h, 0);
|
|
||||||
CloseHandle (h);
|
|
||||||
if (rc == WAIT_OBJECT_0)
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return proc_can_be_signalled (p);
|
|
||||||
}
|
|
||||||
|
|
||||||
sigproc_printf ("it doesn't exist");
|
|
||||||
#if 0
|
|
||||||
/* If the parent pid does not exist, clean this process out of the pinfo
|
|
||||||
* table. It must have died abnormally.
|
|
||||||
*/
|
|
||||||
if ((p->pid == p->ppid) || (p->ppid == 1) || !pid_exists (p->ppid))
|
|
||||||
{
|
|
||||||
p->hProcess = NULL;
|
|
||||||
p->process_state = PID_NOT_IN_USE;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return 1 if this is one of our children, zero otherwise.
|
/* Return 1 if this is one of our children, zero otherwise.
|
||||||
@ -500,22 +460,13 @@ proc_terminate (void)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
ForceCloseHandle1 (pchildren[i]->hProcess, childhProc);
|
ForceCloseHandle1 (pchildren[i]->hProcess, childhProc);
|
||||||
if (!proc_exists (pchildren[i]))
|
sigproc_printf ("%d(%d) closed child handle", pchildren[i]->pid,
|
||||||
{
|
|
||||||
sigproc_printf ("%d(%d) doesn't exist", pchildren[i]->pid,
|
|
||||||
pchildren[i]->dwProcessId);
|
|
||||||
pchildren[i]->process_state = PID_NOT_IN_USE; /* a reaped child CGF FIXME -- still needed? */
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sigproc_printf ("%d(%d) closing active child handle", pchildren[i]->pid,
|
|
||||||
pchildren[i]->dwProcessId);
|
pchildren[i]->dwProcessId);
|
||||||
pchildren[i]->ppid = 1;
|
pchildren[i]->ppid = 1;
|
||||||
if (pchildren[i]->pgid == myself->pid)
|
if (pchildren[i]->pgid == myself->pid)
|
||||||
pchildren[i]->process_state |= PID_ORPHANED;
|
pchildren[i]->process_state |= PID_ORPHANED;
|
||||||
}
|
}
|
||||||
}
|
pchildren[i].release ();
|
||||||
pchildren[i].release (); // FIXME: this breaks older gccs for some reason
|
|
||||||
}
|
}
|
||||||
nchildren = nzombies = 0;
|
nchildren = nzombies = 0;
|
||||||
|
|
||||||
@ -601,6 +552,7 @@ sigproc_init ()
|
|||||||
/* local event signaled when main thread has been dispatched
|
/* local event signaled when main thread has been dispatched
|
||||||
to a signal handler function. */
|
to a signal handler function. */
|
||||||
signal_arrived = CreateEvent(&sec_none_nih, TRUE, FALSE, NULL);
|
signal_arrived = CreateEvent(&sec_none_nih, TRUE, FALSE, NULL);
|
||||||
|
ProtectHandle (signal_arrived);
|
||||||
|
|
||||||
if (!(hwait_sig = makethread (wait_sig, NULL, 0, "sig")))
|
if (!(hwait_sig = makethread (wait_sig, NULL, 0, "sig")))
|
||||||
{
|
{
|
||||||
@ -669,14 +621,6 @@ sigproc_terminate (void)
|
|||||||
WaitForSingleObject (h, 10000);
|
WaitForSingleObject (h, 10000);
|
||||||
ForceCloseHandle1 (h, hwait_sig);
|
ForceCloseHandle1 (h, hwait_sig);
|
||||||
|
|
||||||
/* Exiting thread. Cleanup. Don't set to inactive if a child has been
|
|
||||||
execed with the same pid. */
|
|
||||||
if (!myself->dwProcessId || myself->dwProcessId == GetCurrentProcessId ())
|
|
||||||
myself->process_state &= ~PID_ACTIVE;
|
|
||||||
else
|
|
||||||
sigproc_printf ("Did not clear PID_ACTIVE since %d != %d",
|
|
||||||
myself->dwProcessId, GetCurrentProcessId ());
|
|
||||||
|
|
||||||
/* In case of a sigsuspend */
|
/* In case of a sigsuspend */
|
||||||
SetEvent (signal_arrived);
|
SetEvent (signal_arrived);
|
||||||
|
|
||||||
@ -1052,7 +996,6 @@ remove_zombie (int ci)
|
|||||||
{
|
{
|
||||||
ForceCloseHandle1 (zombies[ci]->hProcess, childhProc);
|
ForceCloseHandle1 (zombies[ci]->hProcess, childhProc);
|
||||||
ForceCloseHandle1 (zombies[ci]->pid_handle, pid_handle);
|
ForceCloseHandle1 (zombies[ci]->pid_handle, pid_handle);
|
||||||
zombies[ci]->process_state = PID_NOT_IN_USE; /* a reaped child */
|
|
||||||
zombies[ci].release ();
|
zombies[ci].release ();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1184,7 +1127,8 @@ wait_sig (VOID *)
|
|||||||
* windows process waiting to see if it's started a cygwin process or not.
|
* windows process waiting to see if it's started a cygwin process or not.
|
||||||
* Signalling subproc_ready indicates that we are a cygwin process.
|
* Signalling subproc_ready indicates that we are a cygwin process.
|
||||||
*/
|
*/
|
||||||
if (child_proc_info && child_proc_info->type == PROC_EXEC)
|
if (child_proc_info &&
|
||||||
|
(child_proc_info->type == PROC_FORK || child_proc_info->type == PROC_SPAWN))
|
||||||
{
|
{
|
||||||
debug_printf ("subproc_ready %p", child_proc_info->subproc_ready);
|
debug_printf ("subproc_ready %p", child_proc_info->subproc_ready);
|
||||||
if (!SetEvent (child_proc_info->subproc_ready))
|
if (!SetEvent (child_proc_info->subproc_ready))
|
||||||
@ -1383,6 +1327,7 @@ WFSO (HANDLE hHandle, DWORD dwMilliseconds)
|
|||||||
DWORD ret;
|
DWORD ret;
|
||||||
sigframe thisframe (mainthread);
|
sigframe thisframe (mainthread);
|
||||||
ret = WaitForSingleObject (hHandle, dwMilliseconds);
|
ret = WaitForSingleObject (hHandle, dwMilliseconds);
|
||||||
|
if (dwMilliseconds > 10 && ret == WAIT_TIMEOUT) system_printf ("TIMED OUT %d\n", dwMilliseconds);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1394,6 +1339,7 @@ WFMO (DWORD nCount, CONST HANDLE *lpHandles, BOOL fWaitAll, DWORD dwMilliseconds
|
|||||||
DWORD ret;
|
DWORD ret;
|
||||||
sigframe thisframe (mainthread);
|
sigframe thisframe (mainthread);
|
||||||
ret = WaitForMultipleObjects (nCount, lpHandles, fWaitAll, dwMilliseconds);
|
ret = WaitForMultipleObjects (nCount, lpHandles, fWaitAll, dwMilliseconds);
|
||||||
|
if (dwMilliseconds > 10 && ret == WAIT_TIMEOUT) system_printf ("TIMED OUT %d\n", dwMilliseconds);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -158,21 +158,6 @@ handle (int n, int direction)
|
|||||||
return fh->get_output_handle ();
|
return fh->get_output_handle ();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Cover function for CreateProcess.
|
|
||||||
|
|
||||||
This function is used by both the routines that search $PATH and those
|
|
||||||
that do not. This should work out ok as according to the documentation,
|
|
||||||
CreateProcess only searches $PATH if PROG has no directory elements.
|
|
||||||
|
|
||||||
Spawning doesn't fit well with Posix's fork/exec (one can argue the merits
|
|
||||||
of either but that's beside the point). If we're exec'ing we want to
|
|
||||||
record the child pid for fork. If we're spawn'ing we don't want to do
|
|
||||||
this. It is up to the caller to handle both cases.
|
|
||||||
|
|
||||||
The result is the process id. The handle of the created process is
|
|
||||||
stored in H.
|
|
||||||
*/
|
|
||||||
|
|
||||||
HANDLE NO_COPY hExeced = NULL;
|
HANDLE NO_COPY hExeced = NULL;
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -252,7 +237,7 @@ public:
|
|||||||
int argc;
|
int argc;
|
||||||
av (int ac, const char * const *av) : calloced (0), argc (ac)
|
av (int ac, const char * const *av) : calloced (0), argc (ac)
|
||||||
{
|
{
|
||||||
argv = (char **) cmalloc (HEAP_1_ARGV, (argc + 1) * sizeof (char *));
|
argv = (char **) cmalloc (HEAP_1_ARGV, (argc + 5) * sizeof (char *));
|
||||||
memcpy (argv, av, (argc + 1) * sizeof (char *));
|
memcpy (argv, av, (argc + 1) * sizeof (char *));
|
||||||
}
|
}
|
||||||
~av ()
|
~av ()
|
||||||
@ -348,16 +333,14 @@ spawn_guts (HANDLE hToken, const char * prog_arg, const char *const *argv,
|
|||||||
si.lpReserved2 = (LPBYTE) &ciresrv;
|
si.lpReserved2 = (LPBYTE) &ciresrv;
|
||||||
si.cbReserved2 = sizeof (ciresrv);
|
si.cbReserved2 = sizeof (ciresrv);
|
||||||
|
|
||||||
HANDLE spr = NULL;
|
|
||||||
DWORD chtype;
|
DWORD chtype;
|
||||||
if (mode != _P_OVERLAY && mode != _P_VFORK)
|
if (mode != _P_OVERLAY && mode != _P_VFORK)
|
||||||
chtype = PROC_SPAWN;
|
chtype = PROC_SPAWN;
|
||||||
else
|
else
|
||||||
{
|
|
||||||
spr = CreateEvent(&sec_all, TRUE, FALSE, NULL);
|
|
||||||
ProtectHandle (spr);
|
|
||||||
chtype = PROC_EXEC;
|
chtype = PROC_EXEC;
|
||||||
}
|
|
||||||
|
HANDLE spr = CreateEvent(&sec_all, TRUE, FALSE, NULL);
|
||||||
|
ProtectHandle (spr);
|
||||||
|
|
||||||
init_child_info (chtype, &ciresrv, (mode == _P_OVERLAY) ? myself->pid : 1, spr);
|
init_child_info (chtype, &ciresrv, (mode == _P_OVERLAY) ? myself->pid : 1, spr);
|
||||||
if (!DuplicateHandle (hMainProc, hMainProc, hMainProc, &ciresrv.parent, 0, 1,
|
if (!DuplicateHandle (hMainProc, hMainProc, hMainProc, &ciresrv.parent, 0, 1,
|
||||||
@ -555,8 +538,6 @@ skip_arg_parsing:
|
|||||||
si.hStdError = handle (2, 1); /* Get output handle */
|
si.hStdError = handle (2, 1); /* Get output handle */
|
||||||
si.cb = sizeof (si);
|
si.cb = sizeof (si);
|
||||||
|
|
||||||
/* Pass fd table to a child */
|
|
||||||
|
|
||||||
syscall_printf ("spawn_guts (%s, %.132s)", (char *) real_path, one_line.buf);
|
syscall_printf ("spawn_guts (%s, %.132s)", (char *) real_path, one_line.buf);
|
||||||
|
|
||||||
int flags = CREATE_DEFAULT_ERROR_MODE | CREATE_SUSPENDED |
|
int flags = CREATE_DEFAULT_ERROR_MODE | CREATE_SUSPENDED |
|
||||||
@ -696,8 +677,6 @@ skip_arg_parsing:
|
|||||||
if (mode == _P_OVERLAY)
|
if (mode == _P_OVERLAY)
|
||||||
{
|
{
|
||||||
strcpy (myself->progname, real_path);
|
strcpy (myself->progname, real_path);
|
||||||
// close_all_files ();
|
|
||||||
proc_terminate ();
|
|
||||||
hExeced = pi.hProcess;
|
hExeced = pi.hProcess;
|
||||||
myself->dwProcessId = pi.dwProcessId;
|
myself->dwProcessId = pi.dwProcessId;
|
||||||
|
|
||||||
@ -765,15 +744,11 @@ skip_arg_parsing:
|
|||||||
CloseHandle (hToken);
|
CloseHandle (hToken);
|
||||||
|
|
||||||
DWORD res;
|
DWORD res;
|
||||||
|
|
||||||
if (mode == _P_OVERLAY || mode == _P_VFORK)
|
|
||||||
{
|
|
||||||
BOOL exited;
|
BOOL exited;
|
||||||
|
|
||||||
HANDLE waitbuf[3] = {pi.hProcess, signal_arrived, spr};
|
HANDLE waitbuf[3] = {pi.hProcess, signal_arrived, spr};
|
||||||
int nwait = 3;
|
int nwait = 3;
|
||||||
|
|
||||||
SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_HIGHEST);
|
|
||||||
res = 0;
|
res = 0;
|
||||||
exited = FALSE;
|
exited = FALSE;
|
||||||
MALLOC_CHECK;
|
MALLOC_CHECK;
|
||||||
@ -789,10 +764,9 @@ skip_arg_parsing:
|
|||||||
res |= exitcode;
|
res |= exitcode;
|
||||||
exited = TRUE;
|
exited = TRUE;
|
||||||
|
|
||||||
if (nwait <= 2 || (res & EXIT_REPARENTING) || (mode != _P_OVERLAY && mode != _P_VFORK))
|
if (nwait > 2 && !(res & EXIT_REPARENTING) &&
|
||||||
/* nothing to do */;
|
(mode == _P_OVERLAY || mode == _P_VFORK))
|
||||||
else if (WaitForSingleObject (spr, 1) == WAIT_OBJECT_0)
|
res |= EXIT_REPARENTING;
|
||||||
goto reparent;
|
|
||||||
break;
|
break;
|
||||||
case WAIT_OBJECT_0 + 1:
|
case WAIT_OBJECT_0 + 1:
|
||||||
sigproc_printf ("signal arrived");
|
sigproc_printf ("signal arrived");
|
||||||
@ -801,7 +775,6 @@ skip_arg_parsing:
|
|||||||
case WAIT_OBJECT_0 + 2:
|
case WAIT_OBJECT_0 + 2:
|
||||||
if (mode == _P_OVERLAY)
|
if (mode == _P_OVERLAY)
|
||||||
{
|
{
|
||||||
reparent:
|
|
||||||
res |= EXIT_REPARENTING;
|
res |= EXIT_REPARENTING;
|
||||||
if (!parent_alive)
|
if (!parent_alive)
|
||||||
{
|
{
|
||||||
@ -812,14 +785,16 @@ skip_arg_parsing:
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case WAIT_FAILED:
|
case WAIT_FAILED:
|
||||||
DWORD r;
|
|
||||||
system_printf ("wait failed: nwait %d, pid %d, winpid %d, %E",
|
system_printf ("wait failed: nwait %d, pid %d, winpid %d, %E",
|
||||||
nwait, myself->pid, myself->dwProcessId);
|
nwait, myself->pid, myself->dwProcessId);
|
||||||
system_printf ("waitbuf[0] %p %d", waitbuf[0],
|
system_printf ("waitbuf[0] %p %d", waitbuf[0],
|
||||||
GetHandleInformation (waitbuf[0], &r));
|
WaitForSingleObject (waitbuf[0], 0));
|
||||||
system_printf ("waitbuf[1] %p = %d", waitbuf[1],
|
system_printf ("waitbuf[1] %p = %d", waitbuf[1],
|
||||||
GetHandleInformation (waitbuf[1], &r));
|
WaitForSingleObject (waitbuf[1], 0));
|
||||||
|
system_printf ("waitbuf[w] %p = %d", waitbuf[2],
|
||||||
|
WaitForSingleObject (waitbuf[2], 0));
|
||||||
set_errno (ECHILD);
|
set_errno (ECHILD);
|
||||||
|
try_to_debug ();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -829,7 +804,7 @@ skip_arg_parsing:
|
|||||||
|
|
||||||
sigproc_printf ("res = %x", res);
|
sigproc_printf ("res = %x", res);
|
||||||
|
|
||||||
if (res & EXIT_REPARENTING)
|
if (mode == _P_OVERLAY && (res & EXIT_REPARENTING))
|
||||||
{
|
{
|
||||||
/* Try to reparent child process.
|
/* Try to reparent child process.
|
||||||
* Make handles to child available to parent process and exit with
|
* Make handles to child available to parent process and exit with
|
||||||
@ -870,7 +845,6 @@ skip_arg_parsing:
|
|||||||
{
|
{
|
||||||
ForceCloseHandle1 (hExeced, childhProc);
|
ForceCloseHandle1 (hExeced, childhProc);
|
||||||
hExeced = INVALID_HANDLE_VALUE;
|
hExeced = INVALID_HANDLE_VALUE;
|
||||||
close_all_files ();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (exited)
|
else if (exited)
|
||||||
@ -880,12 +854,13 @@ skip_arg_parsing:
|
|||||||
}
|
}
|
||||||
|
|
||||||
MALLOC_CHECK;
|
MALLOC_CHECK;
|
||||||
if (mode == _P_OVERLAY)
|
|
||||||
ExitProcess (res);
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (mode)
|
switch (mode)
|
||||||
{
|
{
|
||||||
|
case _P_OVERLAY:
|
||||||
|
proc_terminate ();
|
||||||
|
ExitProcess (0);
|
||||||
|
break;
|
||||||
case _P_WAIT:
|
case _P_WAIT:
|
||||||
waitpid (cygpid, (int *) &res, 0);
|
waitpid (cygpid, (int *) &res, 0);
|
||||||
break;
|
break;
|
||||||
@ -945,7 +920,7 @@ _spawnve (HANDLE hToken, int mode, const char *path, const char *const *argv,
|
|||||||
case _P_WAIT:
|
case _P_WAIT:
|
||||||
case _P_DETACH:
|
case _P_DETACH:
|
||||||
subproc_init ();
|
subproc_init ();
|
||||||
ret = spawn_guts (hToken, path, argv, envp, 0);
|
ret = spawn_guts (hToken, path, argv, envp, mode);
|
||||||
if (vf && ret > 0)
|
if (vf && ret > 0)
|
||||||
{
|
{
|
||||||
vf->pid = ret;
|
vf->pid = ret;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user