* exceptions.cc: (ctrl_c_handler): Do nothing while a Cygwin subprocess is

starting.
* child_info.h (init_child_info): Remove pid argument from declaration.
* cygheap.h (init_cygheap::pid): New element.
* dcrt0.cc (dll_crt0_0): Eliminate handling of now-noexistent cygpid parameter
in child_info struct.  Set forkee to 'true' rather than cygpid since the pid
value was never used.
(dll_crt0_1): Ditto.
(_dll_crt0): Ditto.
* fork.cc (fork_child): Don't wait for sigthread.  This is handled in the fork
call now.
(fork_parent): Remove obsolete pid argument from init_child_info call.  Don't
do anything special with cygpid when DEBUGGING.
(fork): Delay all signals during fork.
(fork_init): Don't do anything special when DEBUGGING.
* pinfo.cc (set_myself): Remove pid parameter.  Use new pid field in cygheap.
(pinfo_init): Don't pass pid argument to set_myself.
* sigproc.cc (sig_send): Wait for dwProcessId to be non-zero as well as
sendsig.
(init_child_info): Eliminate handling of pid.
(wait_sig): Implement method to temporarily hold off sending signals.
* sigproc.h (__SIGHOLD): New enum.
(__SIGNOHOLD): Ditto.
* spawn.cc (spawn_guts): Remove obsolete pid argument from init_child_info
call.
This commit is contained in:
Christopher Faylor 2004-09-12 03:47:57 +00:00
parent ca5ec6685a
commit d584454c82
21 changed files with 235 additions and 216 deletions

View File

@ -1,3 +1,36 @@
2004-09-11 Pierre Humblet <pierre.humblet@ieee.org>
Christopher Faylor <cgf@timesys.com>
* exceptions.cc: (ctrl_c_handler): Do nothing while a Cygwin subprocess
is starting.
2004-09-10 Christopher Faylor <cgf@timesys.com>
* child_info.h (init_child_info): Remove pid argument from declaration.
* cygheap.h (init_cygheap::pid): New element.
* dcrt0.cc (dll_crt0_0): Eliminate handling of now-noexistent cygpid
parameter in child_info struct. Set forkee to 'true' rather than cygpid
since the pid value was never used.
(dll_crt0_1): Ditto.
(_dll_crt0): Ditto.
* fork.cc (fork_child): Don't wait for sigthread. This is handled in
the fork call now.
(fork_parent): Remove obsolete pid argument from init_child_info call. Don't
do anything special with cygpid when DEBUGGING.
(fork): Delay all signals during fork.
(fork_init): Don't do anything special when DEBUGGING.
* pinfo.cc (set_myself): Remove pid parameter. Use new pid field in
cygheap.
(pinfo_init): Don't pass pid argument to set_myself.
* sigproc.cc (sig_send): Wait for dwProcessId to be non-zero as well as
sendsig.
(init_child_info): Eliminate handling of pid.
(wait_sig): Implement method to temporarily hold off sending signals.
* sigproc.h (__SIGHOLD): New enum.
(__SIGNOHOLD): Ditto.
* spawn.cc (spawn_guts): Remove obsolete pid argument from
init_child_info call.
2004-09-10 Corinna Vinschen <corinna@vinschen.de> 2004-09-10 Corinna Vinschen <corinna@vinschen.de>
* fhandler.cc (fhandler_base::dup): Use debug_printf. * fhandler.cc (fhandler_base::dup): Use debug_printf.

View File

@ -42,7 +42,6 @@ public:
DWORD intro; // improbable string DWORD intro; // improbable string
unsigned long magic; // magic number unique to child_info unsigned long magic; // magic number unique to child_info
unsigned short type; // type of record, exec, spawn, fork unsigned short type; // type of record, exec, spawn, fork
int cygpid; // cygwin pid of child process
HANDLE subproc_ready; // used for synchronization with parent HANDLE subproc_ready; // used for synchronization with parent
HANDLE user_h; HANDLE user_h;
HANDLE parent; HANDLE parent;
@ -105,7 +104,7 @@ public:
} }
}; };
void __stdcall init_child_info (DWORD, child_info *, int, HANDLE); void __stdcall init_child_info (DWORD, child_info *, HANDLE);
extern child_info *child_proc_info; extern child_info *child_proc_info;
extern child_info_spawn *spawn_info __attribute__ ((alias ("child_proc_info"))); extern child_info_spawn *spawn_info __attribute__ ((alias ("child_proc_info")));

View File

@ -277,6 +277,7 @@ struct init_cygheap
struct _cygtls **threadlist; struct _cygtls **threadlist;
size_t sthreads; size_t sthreads;
int open_fhs; int open_fhs;
pid_t pid; /* my pid */
void close_ctty (); void close_ctty ();
}; };

View File

@ -605,7 +605,6 @@ dll_crt0_0 ()
GetStartupInfo (&si); GetStartupInfo (&si);
child_proc_info = (child_info *) si.lpReserved2; child_proc_info = (child_info *) si.lpReserved2;
int mypid = 0;
if (si.cbReserved2 < EXEC_MAGIC_SIZE || !child_proc_info if (si.cbReserved2 < EXEC_MAGIC_SIZE || !child_proc_info
|| memcmp (child_proc_info->zero, zeros, || memcmp (child_proc_info->zero, zeros,
sizeof (child_proc_info->zero)) != 0) sizeof (child_proc_info->zero)) != 0)
@ -625,7 +624,7 @@ dll_crt0_0 ()
switch (child_proc_info->type) switch (child_proc_info->type)
{ {
case _PROC_FORK: case _PROC_FORK:
user_data->forkee = child_proc_info->cygpid; user_data->forkee = true;
should_be_cb = sizeof (child_info_fork); should_be_cb = sizeof (child_info_fork);
/* fall through */; /* fall through */;
case _PROC_SPAWN: case _PROC_SPAWN:
@ -639,7 +638,6 @@ dll_crt0_0 ()
else else
{ {
cygwin_user_h = child_proc_info->user_h; cygwin_user_h = child_proc_info->user_h;
mypid = child_proc_info->cygpid;
break; break;
} }
default: default:
@ -667,7 +665,7 @@ dll_crt0_0 ()
alloc_stack (fork_info); alloc_stack (fork_info);
cygheap_fixup_in_child (false); cygheap_fixup_in_child (false);
memory_init (); memory_init ();
set_myself (mypid); set_myself (NULL);
close_ppid_handle = !!child_proc_info->pppid_handle; close_ppid_handle = !!child_proc_info->pppid_handle;
break; break;
case _PROC_SPAWN: case _PROC_SPAWN:
@ -686,7 +684,7 @@ dll_crt0_0 ()
hMainProc, &h, 0, FALSE, hMainProc, &h, 0, FALSE,
DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE)) DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE))
h = NULL; h = NULL;
set_myself (mypid, h); set_myself (h);
__argc = spawn_info->moreinfo->argc; __argc = spawn_info->moreinfo->argc;
__argv = spawn_info->moreinfo->argv; __argv = spawn_info->moreinfo->argv;
envp = spawn_info->moreinfo->envp; envp = spawn_info->moreinfo->envp;
@ -771,7 +769,7 @@ dll_crt0_1 (char *)
_tlsbase = (char *) fork_info->stackbottom; _tlsbase = (char *) fork_info->stackbottom;
_tlstop = (char *) fork_info->stacktop; _tlstop = (char *) fork_info->stacktop;
} }
longjmp (fork_info->jmp, fork_info->cygpid); longjmp (fork_info->jmp, true);
} }
#ifdef DEBUGGING #ifdef DEBUGGING
@ -934,7 +932,7 @@ _dll_crt0 ()
_impure_ptr->_current_locale = "C"; _impure_ptr->_current_locale = "C";
if (child_proc_info && child_proc_info->type == _PROC_FORK) if (child_proc_info && child_proc_info->type == _PROC_FORK)
user_data->forkee = child_proc_info->cygpid; user_data->forkee = true;
else else
__sinit (_impure_ptr); __sinit (_impure_ptr);

View File

@ -805,6 +805,8 @@ ctrl_c_handler (DWORD type)
if (!cygwin_finished_initializing) if (!cygwin_finished_initializing)
{ {
if (myself->ppid_handle) /* Was this process created by a cygwin process? */
return TRUE; /* Yes. Let the parent eventually handle CTRL-C issues. */
debug_printf ("exiting with status %p", STATUS_CONTROL_C_EXIT); debug_printf ("exiting with status %p", STATUS_CONTROL_C_EXIT);
ExitProcess (STATUS_CONTROL_C_EXIT); ExitProcess (STATUS_CONTROL_C_EXIT);
} }

View File

@ -31,12 +31,6 @@ details. */
#include "cygmalloc.h" #include "cygmalloc.h"
#include "cygthread.h" #include "cygthread.h"
#ifdef DEBUGGING
static int npid;
static int npid_max;
static pid_t fork_pids[100];
#endif
/* Timeout to wait for child to start, parent to init child, etc. */ /* Timeout to wait for child to start, parent to init child, etc. */
/* FIXME: Once things stabilize, bump up to a few minutes. */ /* FIXME: Once things stabilize, bump up to a few minutes. */
#define FORK_WAIT_TIMEOUT (300 * 1000) /* 300 seconds */ #define FORK_WAIT_TIMEOUT (300 * 1000) /* 300 seconds */
@ -318,7 +312,6 @@ fork_child (HANDLE& hParent, dll *&first_dll, bool& load_dlls)
pthread::atforkchild (); pthread::atforkchild ();
fixup_timers_after_fork (); fixup_timers_after_fork ();
wait_for_sigthread ();
cygbench ("fork-child"); cygbench ("fork-child");
cygwin_finished_initializing = true; cygwin_finished_initializing = true;
return 0; return 0;
@ -425,7 +418,7 @@ fork_parent (HANDLE& hParent, dll *&first_dll,
ProtectHandleINH (subproc_ready); ProtectHandleINH (subproc_ready);
ProtectHandleINH (forker_finished); ProtectHandleINH (forker_finished);
init_child_info (PROC_FORK, &ch, 1, subproc_ready); init_child_info (PROC_FORK, &ch, subproc_ready);
ch.forker_finished = forker_finished; ch.forker_finished = forker_finished;
@ -439,23 +432,6 @@ fork_parent (HANDLE& hParent, dll *&first_dll,
cygheap->user.deimpersonate (); cygheap->user.deimpersonate ();
ch.parent = hParent; ch.parent = hParent;
#ifdef DEBUGGING
if (npid_max)
{
for (int pass = 0; pass < 2; pass++)
{
pid_t pid;
while ((pid = fork_pids[npid++]))
if (!pinfo (pid))
{
ch.cygpid = pid;
goto out;
}
npid = 0;
}
}
out:
#endif
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);
@ -499,11 +475,7 @@ fork_parent (HANDLE& hParent, dll *&first_dll,
ResumeThread (pi.hThread); ResumeThread (pi.hThread);
} }
#ifdef DEBUGGING
int forked_pid = ch.cygpid != 1 ? ch.cygpid : cygwin_pid (pi.dwProcessId);
#else
int forked_pid = cygwin_pid (pi.dwProcessId); int forked_pid = cygwin_pid (pi.dwProcessId);
#endif
pinfo forked (forked_pid, 1); pinfo forked (forked_pid, 1);
if (!forked) if (!forked)
@ -665,11 +637,13 @@ fork ()
child_info_fork ch; child_info_fork ch;
sig_send (NULL, __SIGHOLD);
int res = setjmp (ch.jmp); int res = setjmp (ch.jmp);
if (res) 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, esp, ch); res = fork_parent (grouped.hParent, grouped.first_dll, grouped.load_dlls, esp, ch);
sig_send (NULL, __SIGNOHOLD);
MALLOC_CHECK; MALLOC_CHECK;
syscall_printf ("%d = fork()", res); syscall_printf ("%d = fork()", res);
@ -679,13 +653,6 @@ fork ()
void void
fork_init () fork_init ()
{ {
char buf[1024];
if (!GetEnvironmentVariable ("CYGWIN_FORK_PIDS", buf, 1024))
return;
pid_t pid;
char *p, *pe;
for (p = buf; (pid = strtol (p, &pe, 10)); p = pe)
fork_pids[npid_max++] = pid;
} }
#endif /*DEBUGGING*/ #endif /*DEBUGGING*/

View File

@ -58,19 +58,18 @@ pinfo_fixup_after_fork ()
This is done once when the dll is first loaded. */ This is done once when the dll is first loaded. */
void __stdcall void __stdcall
set_myself (pid_t pid, HANDLE h) set_myself (HANDLE h)
{ {
DWORD winpid = GetCurrentProcessId (); if (!h)
if (pid == 1) cygheap->pid = cygwin_pid (GetCurrentProcessId ());
pid = cygwin_pid (winpid); myself.init (cygheap->pid, PID_IN_USE | PID_MYSELF, h);
myself.init (pid, PID_IN_USE | PID_MYSELF, h);
myself->dwProcessId = winpid;
myself->process_state |= PID_IN_USE; myself->process_state |= PID_IN_USE;
myself->start_time = time (NULL); /* Register our starting time. */ myself->start_time = time (NULL); /* Register our starting time. */
(void) GetModuleFileName (NULL, myself->progname, sizeof (myself->progname)); (void) GetModuleFileName (NULL, myself->progname, sizeof (myself->progname));
if (!strace.active) if (!strace.active)
strace.hello (); strace.hello ();
debug_printf ("myself->dwProcessId %u", myself->dwProcessId);
InitializeCriticalSection (&myself->lock); InitializeCriticalSection (&myself->lock);
return; return;
} }
@ -90,7 +89,7 @@ pinfo_init (char **envp, int envc)
{ {
/* Invent our own pid. */ /* Invent our own pid. */
set_myself (1); set_myself (NULL);
myself->ppid = 1; myself->ppid = 1;
myself->pgid = myself->sid = myself->pid; myself->pgid = myself->sid = myself->pid;
myself->ctty = -1; myself->ctty = -1;

View File

@ -707,6 +707,8 @@ sig_send (_pinfo *p, siginfo_t& si, _cygtls *tls)
sendsig = myself->sendsig; sendsig = myself->sendsig;
else else
{ {
for (int i = 0; !p->dwProcessId && i < 10000; i++)
low_priority_sleep (0);
HANDLE hp = OpenProcess (PROCESS_DUP_HANDLE, false, p->dwProcessId); HANDLE hp = OpenProcess (PROCESS_DUP_HANDLE, false, p->dwProcessId);
if (!hp) if (!hp)
{ {
@ -854,14 +856,13 @@ subproc_init (void)
by fork/spawn/exec. */ by fork/spawn/exec. */
void __stdcall void __stdcall
init_child_info (DWORD chtype, child_info *ch, pid_t pid, HANDLE subproc_ready) init_child_info (DWORD chtype, child_info *ch, HANDLE subproc_ready)
{ {
memset (ch, 0, sizeof *ch); memset (ch, 0, sizeof *ch);
ch->cb = chtype == PROC_FORK ? sizeof (child_info_fork) : sizeof (child_info); ch->cb = chtype == PROC_FORK ? sizeof (child_info_fork) : sizeof (child_info);
ch->intro = PROC_MAGIC_GENERIC; ch->intro = PROC_MAGIC_GENERIC;
ch->magic = CHILD_INFO_MAGIC; ch->magic = CHILD_INFO_MAGIC;
ch->type = chtype; ch->type = chtype;
ch->cygpid = pid;
ch->subproc_ready = subproc_ready; ch->subproc_ready = subproc_ready;
ch->pppid_handle = myself->ppid_handle; ch->pppid_handle = myself->ppid_handle;
ch->fhandler_union_cb = sizeof (fhandler_union); ch->fhandler_union_cb = sizeof (fhandler_union);
@ -1064,6 +1065,7 @@ wait_sig (VOID *self)
{ {
HANDLE readsig; HANDLE readsig;
char sa_buf[1024]; char sa_buf[1024];
Static bool holding_signals;
/* Initialization */ /* Initialization */
(void) SetThreadPriority (GetCurrentThread (), WAIT_SIG_PRIORITY); (void) SetThreadPriority (GetCurrentThread (), WAIT_SIG_PRIORITY);
@ -1080,6 +1082,7 @@ wait_sig (VOID *self)
myself->process_state |= PID_ACTIVE; myself->process_state |= PID_ACTIVE;
myself->process_state &= ~PID_INITIALIZING; myself->process_state &= ~PID_INITIALIZING;
sigproc_printf ("myself->dwProcessId %u", myself->dwProcessId);
/* If we've been execed, then there is still a stub left in the previous /* If we've been execed, then there is still a stub left in the previous
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. */
@ -1159,9 +1162,17 @@ wait_sig (VOID *self)
if (q->si.si_signo == __SIGDELETE || q->process () > 0) if (q->si.si_signo == __SIGDELETE || q->process () > 0)
sigq.del (); sigq.del ();
break; break;
case __SIGHOLD:
holding_signals = 1;
break;
case __SIGNOHOLD:
holding_signals = 0;
break;
default: default:
if (pack.si.si_signo < 0) if (pack.si.si_signo < 0)
sig_clear (-pack.si.si_signo); sig_clear (-pack.si.si_signo);
else if (holding_signals)
sigq.add (pack);
else else
{ {
int sig = pack.si.si_signo; int sig = pack.si.si_signo;

View File

@ -24,7 +24,9 @@ enum
__SIGCOMMUNE = -(NSIG + 3), __SIGCOMMUNE = -(NSIG + 3),
__SIGPENDING = -(NSIG + 4), __SIGPENDING = -(NSIG + 4),
__SIGDELETE = -(NSIG + 5), __SIGDELETE = -(NSIG + 5),
__SIGFLUSHFAST = -(NSIG + 6) __SIGFLUSHFAST = -(NSIG + 6),
__SIGHOLD = -(NSIG + 7),
__SIGNOHOLD = -(NSIG + 8)
}; };
#endif #endif

View File

@ -393,8 +393,7 @@ spawn_guts (const char * prog_arg, const char *const *argv,
ProtectHandleINH (subproc_ready); ProtectHandleINH (subproc_ready);
} }
init_child_info (chtype, &ciresrv, (mode == _P_OVERLAY) ? myself->pid : 1, init_child_info (chtype, &ciresrv, subproc_ready);
subproc_ready);
ciresrv.moreinfo = (cygheap_exec_info *) ccalloc (HEAP_1_EXEC, 1, sizeof (cygheap_exec_info)); ciresrv.moreinfo = (cygheap_exec_info *) ccalloc (HEAP_1_EXEC, 1, sizeof (cygheap_exec_info));
ciresrv.moreinfo->old_title = NULL; ciresrv.moreinfo->old_title = NULL;
@ -630,6 +629,10 @@ spawn_guts (const char * prog_arg, const char *const *argv,
flags |= DETACHED_PROCESS; flags |= DETACHED_PROCESS;
if (mode != _P_OVERLAY) if (mode != _P_OVERLAY)
flags |= CREATE_SUSPENDED; flags |= CREATE_SUSPENDED;
#if 0 //someday
else
myself->dwProcessId = 0;
#endif
/* Some file types (currently only sockets) need extra effort in the /* Some file types (currently only sockets) need extra effort in the
parent after CreateProcess and before copying the datastructures parent after CreateProcess and before copying the datastructures
@ -638,7 +641,6 @@ spawn_guts (const char * prog_arg, const char *const *argv,
if (cygheap->fdtab.need_fixup_before ()) if (cygheap->fdtab.need_fixup_before ())
flags |= CREATE_SUSPENDED; flags |= CREATE_SUSPENDED;
const char *runpath = null_app_name ? NULL : (const char *) real_path; const char *runpath = null_app_name ? NULL : (const char *) real_path;
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);
@ -649,6 +651,7 @@ spawn_guts (const char * prog_arg, const char *const *argv,
cygheap->fdtab.set_file_pointers_for_exec (); cygheap->fdtab.set_file_pointers_for_exec ();
cygheap->user.deimpersonate (); cygheap->user.deimpersonate ();
/* 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.
@ -729,6 +732,10 @@ spawn_guts (const char * prog_arg, const char *const *argv,
{ {
__seterrno (); __seterrno ();
syscall_printf ("CreateProcess failed, %E"); syscall_printf ("CreateProcess failed, %E");
#if 0 // someday
if (mode == _P_OVERLAY)
myself->dwProcessId = GetCurrentProcessId ();
#endif
if (subproc_ready) if (subproc_ready)
ForceCloseHandle (subproc_ready); ForceCloseHandle (subproc_ready);
cygheap_setup_for_child_cleanup (newheap, &ciresrv, 0); cygheap_setup_for_child_cleanup (newheap, &ciresrv, 0);