4
0
mirror of git://sourceware.org/git/newlib-cygwin.git synced 2025-01-19 21:09:22 +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:
Christopher Faylor 2000-10-14 05:52:38 +00:00
parent cbe4c8e234
commit aece55b982
9 changed files with 154 additions and 244 deletions

View File

@ -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>
* dtable.cc (dtable::fixup_after_fork): Revert thinko below.

View File

@ -207,9 +207,7 @@ cygheap_fixup_in_child (HANDLE parent, bool execed)
/* Copy memory from the parent */
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",
n, m);

View File

@ -973,7 +973,6 @@ enum
extern "C" void __stdcall
do_exit (int status)
{
BOOL cleanup_pinfo;
UINT n = (UINT) status;
static int NO_COPY exit_state = 0;
@ -1013,10 +1012,7 @@ do_exit (int status)
}
if (n & EXIT_REPARENTING)
{
n &= ~EXIT_REPARENTING;
cleanup_pinfo = FALSE;
}
else
{
myself->stopsig = 0;
@ -1045,7 +1041,6 @@ do_exit (int status)
}
tty_terminate ();
cleanup_pinfo = TRUE;
}
window_terminate ();
@ -1060,11 +1055,6 @@ do_exit (int status)
ForceCloseHandle1 (hExeced, childhProc);
}
if (cleanup_pinfo)
myself->record_death ();
else
sigproc_printf ("not cleanup_pinfo");
shared_terminate ();
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
our process_state. */
sigproc_terminate ();
myself->record_death ();
#ifdef DEBUGGING
(void) try_to_debug ();
#endif

View File

@ -1005,11 +1005,7 @@ signal_exit (int rc)
{
rc = EXIT_SIGNAL | (rc << 8);
if (exit_already++)
{
/* We are going down - reset our process_state without locking. */
myself->record_death ();
ExitProcess (rc);
}
/* 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

View File

@ -308,10 +308,9 @@ debug_printf ("hParent %p", hParent);
}
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;
void *stack_here = &hParent;
DWORD rc;
PROCESS_INFORMATION pi = {0, NULL, 0, 0};
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,
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)
CloseHandle (console_handle);
else
@ -407,7 +404,9 @@ fork_parent (HANDLE& hParent, dll *&first_dll, bool& load_dlls, child_info_fork
ch.cygheap_max = cygheap_max;
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 */
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;
} grouped;
int res;
int x;
MALLOC_CHECK;
// grow_stack_slack ();
debug_printf ("entering");
grouped.hParent = grouped.first_dll = NULL;
grouped.load_dlls = 0;
if (ISSTATE(myself, PID_SPLIT_HEAP))
{
@ -597,13 +593,17 @@ fork ()
return -1;
}
child_info_fork ch;
x = setjmp (ch.jmp);
void *esp;
__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);
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;
syscall_printf ("%d = fork()", res);

View File

@ -174,17 +174,6 @@ _pinfo::copysigs(_pinfo *_other)
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
pinfo::init (pid_t n, DWORD create, HANDLE in_h)
{

View File

@ -119,8 +119,6 @@ private:
public:
/* Pointer to mmap'ed areas for this process. Set up by fork. */
void *mmap_ptr;
void record_death ();
};
class pinfo

View File

@ -205,48 +205,8 @@ proc_exists (_pinfo *p)
if (p == NULL)
return FALSE;
if (p == myself || p == myself_nowait_nonmain || p == myself_nowait)
else
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.
@ -500,22 +460,13 @@ proc_terminate (void)
else
{
ForceCloseHandle1 (pchildren[i]->hProcess, childhProc);
if (!proc_exists (pchildren[i]))
{
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,
sigproc_printf ("%d(%d) closed child handle", pchildren[i]->pid,
pchildren[i]->dwProcessId);
pchildren[i]->ppid = 1;
if (pchildren[i]->pgid == myself->pid)
pchildren[i]->process_state |= PID_ORPHANED;
}
}
pchildren[i].release (); // FIXME: this breaks older gccs for some reason
pchildren[i].release ();
}
nchildren = nzombies = 0;
@ -601,6 +552,7 @@ sigproc_init ()
/* local event signaled when main thread has been dispatched
to a signal handler function. */
signal_arrived = CreateEvent(&sec_none_nih, TRUE, FALSE, NULL);
ProtectHandle (signal_arrived);
if (!(hwait_sig = makethread (wait_sig, NULL, 0, "sig")))
{
@ -669,14 +621,6 @@ sigproc_terminate (void)
WaitForSingleObject (h, 10000);
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 */
SetEvent (signal_arrived);
@ -1052,7 +996,6 @@ remove_zombie (int ci)
{
ForceCloseHandle1 (zombies[ci]->hProcess, childhProc);
ForceCloseHandle1 (zombies[ci]->pid_handle, pid_handle);
zombies[ci]->process_state = PID_NOT_IN_USE; /* a reaped child */
zombies[ci].release ();
}
@ -1184,7 +1127,8 @@ wait_sig (VOID *)
* windows process waiting to see if it's started a cygwin process or not.
* Signalling subproc_ready indicates that we are a cygwin process.
*/
if (child_proc_info && child_proc_info->type == PROC_EXEC)
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);
if (!SetEvent (child_proc_info->subproc_ready))
@ -1383,6 +1327,7 @@ WFSO (HANDLE hHandle, DWORD dwMilliseconds)
DWORD ret;
sigframe thisframe (mainthread);
ret = WaitForSingleObject (hHandle, dwMilliseconds);
if (dwMilliseconds > 10 && ret == WAIT_TIMEOUT) system_printf ("TIMED OUT %d\n", dwMilliseconds);
return ret;
}
@ -1394,6 +1339,7 @@ WFMO (DWORD nCount, CONST HANDLE *lpHandles, BOOL fWaitAll, DWORD dwMilliseconds
DWORD ret;
sigframe thisframe (mainthread);
ret = WaitForMultipleObjects (nCount, lpHandles, fWaitAll, dwMilliseconds);
if (dwMilliseconds > 10 && ret == WAIT_TIMEOUT) system_printf ("TIMED OUT %d\n", dwMilliseconds);
return ret;
}
}

View File

@ -158,21 +158,6 @@ handle (int n, int direction)
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;
int
@ -252,7 +237,7 @@ public:
int argc;
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 *));
}
~av ()
@ -348,16 +333,14 @@ spawn_guts (HANDLE hToken, const char * prog_arg, const char *const *argv,
si.lpReserved2 = (LPBYTE) &ciresrv;
si.cbReserved2 = sizeof (ciresrv);
HANDLE spr = NULL;
DWORD chtype;
if (mode != _P_OVERLAY && mode != _P_VFORK)
chtype = PROC_SPAWN;
else
{
spr = CreateEvent(&sec_all, TRUE, FALSE, NULL);
ProtectHandle (spr);
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);
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.cb = sizeof (si);
/* Pass fd table to a child */
syscall_printf ("spawn_guts (%s, %.132s)", (char *) real_path, one_line.buf);
int flags = CREATE_DEFAULT_ERROR_MODE | CREATE_SUSPENDED |
@ -696,8 +677,6 @@ skip_arg_parsing:
if (mode == _P_OVERLAY)
{
strcpy (myself->progname, real_path);
// close_all_files ();
proc_terminate ();
hExeced = pi.hProcess;
myself->dwProcessId = pi.dwProcessId;
@ -765,15 +744,11 @@ skip_arg_parsing:
CloseHandle (hToken);
DWORD res;
if (mode == _P_OVERLAY || mode == _P_VFORK)
{
BOOL exited;
HANDLE waitbuf[3] = {pi.hProcess, signal_arrived, spr};
int nwait = 3;
SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_HIGHEST);
res = 0;
exited = FALSE;
MALLOC_CHECK;
@ -789,10 +764,9 @@ skip_arg_parsing:
res |= exitcode;
exited = TRUE;
if (nwait <= 2 || (res & EXIT_REPARENTING) || (mode != _P_OVERLAY && mode != _P_VFORK))
/* nothing to do */;
else if (WaitForSingleObject (spr, 1) == WAIT_OBJECT_0)
goto reparent;
if (nwait > 2 && !(res & EXIT_REPARENTING) &&
(mode == _P_OVERLAY || mode == _P_VFORK))
res |= EXIT_REPARENTING;
break;
case WAIT_OBJECT_0 + 1:
sigproc_printf ("signal arrived");
@ -801,7 +775,6 @@ skip_arg_parsing:
case WAIT_OBJECT_0 + 2:
if (mode == _P_OVERLAY)
{
reparent:
res |= EXIT_REPARENTING;
if (!parent_alive)
{
@ -812,14 +785,16 @@ skip_arg_parsing:
}
break;
case WAIT_FAILED:
DWORD r;
system_printf ("wait failed: nwait %d, pid %d, winpid %d, %E",
nwait, myself->pid, myself->dwProcessId);
system_printf ("waitbuf[0] %p %d", waitbuf[0],
GetHandleInformation (waitbuf[0], &r));
WaitForSingleObject (waitbuf[0], 0));
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);
try_to_debug ();
return -1;
}
break;
@ -829,7 +804,7 @@ skip_arg_parsing:
sigproc_printf ("res = %x", res);
if (res & EXIT_REPARENTING)
if (mode == _P_OVERLAY && (res & EXIT_REPARENTING))
{
/* Try to reparent child process.
* Make handles to child available to parent process and exit with
@ -870,7 +845,6 @@ skip_arg_parsing:
{
ForceCloseHandle1 (hExeced, childhProc);
hExeced = INVALID_HANDLE_VALUE;
close_all_files ();
}
}
else if (exited)
@ -880,12 +854,13 @@ skip_arg_parsing:
}
MALLOC_CHECK;
if (mode == _P_OVERLAY)
ExitProcess (res);
}
switch (mode)
{
case _P_OVERLAY:
proc_terminate ();
ExitProcess (0);
break;
case _P_WAIT:
waitpid (cygpid, (int *) &res, 0);
break;
@ -945,7 +920,7 @@ _spawnve (HANDLE hToken, int mode, const char *path, const char *const *argv,
case _P_WAIT:
case _P_DETACH:
subproc_init ();
ret = spawn_guts (hToken, path, argv, envp, 0);
ret = spawn_guts (hToken, path, argv, envp, mode);
if (vf && ret > 0)
{
vf->pid = ret;