* exceptions.cc (interrupt_setup): Move actions from setup_handler to here.
(setup_handler): Move actions after a successful interrupt to interrupt_setup. * fork.cc (vfork): Augment debugging output. * sigproc.cc (proc_subproc): Ditto. * spawn.cc (spawn_guts): Ditto. Correctly fill out progname when spawn NO_WAIT. Call signal handler when a signal arrives. * sigproc.h: Declare a function.
This commit is contained in:
parent
50b1264871
commit
125205875b
@ -1,3 +1,15 @@
|
|||||||
|
Sun Jun 24 17:38:19 2001 Christopher Faylor <cgf@cygnus.com>
|
||||||
|
|
||||||
|
* exceptions.cc (interrupt_setup): Move actions from setup_handler to
|
||||||
|
here.
|
||||||
|
(setup_handler): Move actions after a successful interrupt to
|
||||||
|
interrupt_setup.
|
||||||
|
* fork.cc (vfork): Augment debugging output.
|
||||||
|
* sigproc.cc (proc_subproc): Ditto.
|
||||||
|
* spawn.cc (spawn_guts): Ditto. Correctly fill out progname when spawn
|
||||||
|
NO_WAIT. Call signal handler when a signal arrives.
|
||||||
|
* sigproc.h: Declare a function.
|
||||||
|
|
||||||
Fri Jun 22 16:50:00 2001 Corinna Vinschen <corinna@vinschen.de>
|
Fri Jun 22 16:50:00 2001 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
* fhandler.h class fhandler_socket): Declare new method
|
* fhandler.h class fhandler_socket): Declare new method
|
||||||
|
@ -684,6 +684,10 @@ interrupt_setup (int sig, void *handler, DWORD retaddr, DWORD *retaddr_on_stack,
|
|||||||
myself->stopsig = 0;
|
myself->stopsig = 0;
|
||||||
myself->process_state |= PID_STOPPED;
|
myself->process_state |= PID_STOPPED;
|
||||||
}
|
}
|
||||||
|
/* Clear any waiting threads prior to dispatching to handler function */
|
||||||
|
proc_subproc (PROC_CLEARWAIT, 1);
|
||||||
|
int res = SetEvent (signal_arrived); // For an EINTR case
|
||||||
|
sigproc_printf ("armed signal_arrived %p, res %d", signal_arrived, res);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool interrupt_now (CONTEXT *, int, void *, struct sigaction&) __attribute__((regparm(3)));
|
static bool interrupt_now (CONTEXT *, int, void *, struct sigaction&) __attribute__((regparm(3)));
|
||||||
@ -692,7 +696,7 @@ interrupt_now (CONTEXT *ctx, int sig, void *handler, struct sigaction& siga)
|
|||||||
{
|
{
|
||||||
interrupt_setup (sig, handler, ctx->Eip, 0, siga);
|
interrupt_setup (sig, handler, ctx->Eip, 0, siga);
|
||||||
ctx->Eip = (DWORD) sigdelayed;
|
ctx->Eip = (DWORD) sigdelayed;
|
||||||
SetThreadContext (myself->getthread2signal (), ctx); /* Restart the thread */
|
SetThreadContext (myself->getthread2signal (), ctx); /* Restart the thread in a new location */
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -853,7 +857,9 @@ setup_handler (int sig, void *handler, struct sigaction& siga)
|
|||||||
}
|
}
|
||||||
|
|
||||||
set_pending:
|
set_pending:
|
||||||
if (!interrupted)
|
if (interrupted)
|
||||||
|
res = 1;
|
||||||
|
else
|
||||||
{
|
{
|
||||||
pending_signals = 1; /* FIXME: Probably need to be more tricky here */
|
pending_signals = 1; /* FIXME: Probably need to be more tricky here */
|
||||||
sig_set_pending (sig);
|
sig_set_pending (sig);
|
||||||
@ -861,13 +867,6 @@ setup_handler (int sig, void *handler, struct sigaction& siga)
|
|||||||
Sleep (0); /* Hopefully, other process will be waking up soon. */
|
Sleep (0); /* Hopefully, other process will be waking up soon. */
|
||||||
sigproc_printf ("couldn't send signal %d", sig);
|
sigproc_printf ("couldn't send signal %d", sig);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Clear any waiting threads prior to dispatching to handler function */
|
|
||||||
proc_subproc (PROC_CLEARWAIT, 1);
|
|
||||||
res = SetEvent (signal_arrived); // For an EINTR case
|
|
||||||
sigproc_printf ("armed signal_arrived %p, res %d", signal_arrived, res);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (th)
|
if (th)
|
||||||
LeaveCriticalSection (&th->lock);
|
LeaveCriticalSection (&th->lock);
|
||||||
@ -1157,68 +1156,61 @@ void unused_sig_wrapper ()
|
|||||||
to restore any mask, restores any potentially clobbered registers
|
to restore any mask, restores any potentially clobbered registers
|
||||||
and returns to original caller. */
|
and returns to original caller. */
|
||||||
__asm__ volatile ("\n\
|
__asm__ volatile ("\n\
|
||||||
.text\n\
|
.text \n\
|
||||||
\n\
|
_sigreturn: \n\
|
||||||
_sigreturn:\n\
|
addl $4,%%esp # Remove argument \n\
|
||||||
addl $4,%%esp # Remove argument\n\
|
movl %%esp,%%ebp \n\
|
||||||
movl %%esp,%%ebp\n\
|
addl $36,%%ebp \n\
|
||||||
addl $36,%%ebp\n\
|
call _set_process_mask@4 \n\
|
||||||
\n\
|
\n\
|
||||||
cmpl $0,%4 # Did a signal come in?\n\
|
cmpl $0,%4 # Did a signal come in? \n\
|
||||||
jz 1f # No, if zero\n\
|
jz 1f # No, if zero \n\
|
||||||
call _call_signal_handler_now@0 # yes handle the signal\n\
|
call _call_signal_handler_now@0 # yes handle the signal \n\
|
||||||
\n\
|
\n\
|
||||||
# FIXME: There is a race here. The signal handler could set up\n\
|
1: popl %%eax # saved errno \n\
|
||||||
# the sigsave structure between _call_signal_handler and the\n\
|
testl %%eax,%%eax # Is it < 0 \n\
|
||||||
# end of _set_process_mask. This would make cygwin detect an\n\
|
jl 2f # yup. ignore it \n\
|
||||||
# incorrect signal mask.\n\
|
movl %1,%%ebx \n\
|
||||||
\n\
|
movl %%eax,(%%ebx) \n\
|
||||||
1: call _set_process_mask@4\n\
|
2: popl %%eax \n\
|
||||||
popl %%eax # saved errno\n\
|
popl %%ebx \n\
|
||||||
testl %%eax,%%eax # Is it < 0\n\
|
popl %%ecx \n\
|
||||||
jl 2f # yup. ignore it\n\
|
popl %%edx \n\
|
||||||
movl %1,%%ebx\n\
|
popl %%edi \n\
|
||||||
movl %%eax,(%%ebx)\n\
|
popl %%esi \n\
|
||||||
2: popl %%eax\n\
|
popf \n\
|
||||||
popl %%ebx\n\
|
popl %%ebp \n\
|
||||||
popl %%ecx\n\
|
ret \n\
|
||||||
popl %%edx\n\
|
\n\
|
||||||
popl %%edi\n\
|
__no_sig_start: \n\
|
||||||
popl %%esi\n\
|
_sigdelayed: \n\
|
||||||
popf\n\
|
pushl %2 # original return address \n\
|
||||||
popl %%ebp\n\
|
_sigdelayed0: \n\
|
||||||
ret\n\
|
pushl %%ebp \n\
|
||||||
\n\
|
movl %%esp,%%ebp \n\
|
||||||
__no_sig_start:\n\
|
pushf \n\
|
||||||
_sigdelayed:\n\
|
pushl %%esi \n\
|
||||||
pushl %2 # original return address\n\
|
pushl %%edi \n\
|
||||||
_sigdelayed0:\n\
|
pushl %%edx \n\
|
||||||
pushl %%ebp\n\
|
pushl %%ecx \n\
|
||||||
movl %%esp,%%ebp\n\
|
pushl %%ebx \n\
|
||||||
pushf\n\
|
pushl %%eax \n\
|
||||||
pushl %%esi\n\
|
pushl %7 # saved errno \n\
|
||||||
pushl %%edi\n\
|
pushl %3 # oldmask \n\
|
||||||
pushl %%edx\n\
|
pushl %4 # signal argument \n\
|
||||||
pushl %%ecx\n\
|
pushl $_sigreturn \n\
|
||||||
pushl %%ebx\n\
|
\n\
|
||||||
pushl %%eax\n\
|
call _reset_signal_arrived@0 \n\
|
||||||
pushl %7 # saved errno\n\
|
pushl %5 # signal number \n\
|
||||||
pushl %3 # oldmask\n\
|
pushl %8 # newmask \n\
|
||||||
pushl %4 # signal argument\n\
|
movl $0,%0 # zero the signal number as a \n\
|
||||||
pushl $_sigreturn\n\
|
|
||||||
\n\
|
|
||||||
call _reset_signal_arrived@0\n\
|
|
||||||
pushl %5 # signal number\n\
|
|
||||||
pushl %8 # newmask\n\
|
|
||||||
movl $0,%0 # zero the signal number as a\n\
|
|
||||||
# flag to the signal handler thread\n\
|
# flag to the signal handler thread\n\
|
||||||
# that it is ok to set up sigsave\n\
|
# that it is ok to set up sigsave\n\
|
||||||
\n\
|
\n\
|
||||||
call _set_process_mask@4\n\
|
call _set_process_mask@4 \n\
|
||||||
popl %%eax\n\
|
popl %%eax \n\
|
||||||
jmp *%%eax\n\
|
jmp *%%eax \n\
|
||||||
__no_sig_end:\n\
|
__no_sig_end: \n\
|
||||||
\n\
|
|
||||||
" : "=m" (sigsave.sig) : "m" (&_impure_ptr->_errno),
|
" : "=m" (sigsave.sig) : "m" (&_impure_ptr->_errno),
|
||||||
"g" (sigsave.retaddr), "g" (sigsave.oldmask), "g" (sigsave.sig),
|
"g" (sigsave.retaddr), "g" (sigsave.oldmask), "g" (sigsave.sig),
|
||||||
"g" (sigsave.func), "o" (pid_offset), "g" (sigsave.saved_errno), "g" (sigsave.newmask)
|
"g" (sigsave.func), "o" (pid_offset), "g" (sigsave.saved_errno), "g" (sigsave.newmask)
|
||||||
|
@ -708,7 +708,9 @@ vfork ()
|
|||||||
for (pp = (char **)vf->frame, esp = vf->vfork_esp;
|
for (pp = (char **)vf->frame, esp = vf->vfork_esp;
|
||||||
esp <= vf->vfork_ebp + 1; pp++, esp++)
|
esp <= vf->vfork_ebp + 1; pp++, esp++)
|
||||||
*pp = *esp;
|
*pp = *esp;
|
||||||
return cygheap->fdtab.vfork_child_dup () ? 0 : -1;
|
int res = cygheap->fdtab.vfork_child_dup () ? 0 : -1;
|
||||||
|
debug_printf ("%d = vfork()", res);
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
cygheap->fdtab.vfork_parent_restore ();
|
cygheap->fdtab.vfork_parent_restore ();
|
||||||
|
@ -306,7 +306,7 @@ proc_subproc (DWORD what, DWORD val)
|
|||||||
zombies[nzombies] = pchildren[val]; // Add to zombie array
|
zombies[nzombies] = pchildren[val]; // Add to zombie array
|
||||||
zombies[nzombies++]->process_state = PID_ZOMBIE;// Walking dead
|
zombies[nzombies++]->process_state = PID_ZOMBIE;// Walking dead
|
||||||
|
|
||||||
sigproc_printf ("removing [%d], pid %d, handle %p, nchildren %d",
|
sigproc_printf ("zombifying [%d], pid %d, handle %p, nchildren %d",
|
||||||
val, pchildren[val]->pid, hchildren[val], nchildren);
|
val, pchildren[val]->pid, hchildren[val], nchildren);
|
||||||
if ((int) val < --nchildren)
|
if ((int) val < --nchildren)
|
||||||
{
|
{
|
||||||
|
@ -96,6 +96,7 @@ extern HANDLE signal_arrived;
|
|||||||
BOOL __stdcall my_parent_is_alive ();
|
BOOL __stdcall my_parent_is_alive ();
|
||||||
extern "C" int __stdcall sig_dispatch_pending (int force = FALSE);
|
extern "C" int __stdcall sig_dispatch_pending (int force = FALSE);
|
||||||
extern "C" void __stdcall set_process_mask (sigset_t newmask);
|
extern "C" void __stdcall set_process_mask (sigset_t newmask);
|
||||||
|
extern "C" void __stdcall reset_signal_arrived ();
|
||||||
int __stdcall sig_handle (int);
|
int __stdcall sig_handle (int);
|
||||||
void __stdcall sig_clear (int);
|
void __stdcall sig_clear (int);
|
||||||
void __stdcall sig_set_pending (int);
|
void __stdcall sig_set_pending (int);
|
||||||
|
@ -302,7 +302,7 @@ spawn_guts (HANDLE hToken, const char * prog_arg, const char *const *argv,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
syscall_printf ("spawn_guts (%.132s)", prog_arg);
|
syscall_printf ("spawn_guts (%d, %.132s)", mode, prog_arg);
|
||||||
|
|
||||||
if (argv == NULL)
|
if (argv == NULL)
|
||||||
{
|
{
|
||||||
@ -708,9 +708,9 @@ skip_arg_parsing:
|
|||||||
{
|
{
|
||||||
/* These are both duplicated in the child code. We do this here,
|
/* These are both duplicated in the child code. We do this here,
|
||||||
primarily for strace. */
|
primarily for strace. */
|
||||||
strcpy (myself->progname, real_path);
|
|
||||||
strace.execing = 1;
|
strace.execing = 1;
|
||||||
hExeced = pi.hProcess;
|
hExeced = pi.hProcess;
|
||||||
|
strcpy (myself->progname, real_path);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -723,10 +723,10 @@ skip_arg_parsing:
|
|||||||
syscall_printf ("-1 = spawnve (), process table full");
|
syscall_printf ("-1 = spawnve (), process table full");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
child->progname[0] = '\0';
|
|
||||||
child->dwProcessId = pi.dwProcessId;
|
child->dwProcessId = pi.dwProcessId;
|
||||||
child->hProcess = pi.hProcess;
|
child->hProcess = pi.hProcess;
|
||||||
child.remember ();
|
child.remember ();
|
||||||
|
strcpy (child->progname, real_path);
|
||||||
/* Start the child running */
|
/* Start the child running */
|
||||||
ResumeThread (pi.hThread);
|
ResumeThread (pi.hThread);
|
||||||
}
|
}
|
||||||
@ -761,7 +761,8 @@ skip_arg_parsing:
|
|||||||
break;
|
break;
|
||||||
case WAIT_OBJECT_0 + 1:
|
case WAIT_OBJECT_0 + 1:
|
||||||
sigproc_printf ("signal arrived");
|
sigproc_printf ("signal arrived");
|
||||||
ResetEvent (signal_arrived);
|
// reset_signal_arrived ();
|
||||||
|
thisframe.call_signal_handler ();
|
||||||
continue;
|
continue;
|
||||||
case WAIT_OBJECT_0 + 2:
|
case WAIT_OBJECT_0 + 2:
|
||||||
if (mode == _P_OVERLAY)
|
if (mode == _P_OVERLAY)
|
||||||
@ -890,6 +891,7 @@ _spawnve (HANDLE hToken, int mode, const char *path, const char *const *argv,
|
|||||||
ret = spawn_guts (hToken, path, argv, envp, mode);
|
ret = spawn_guts (hToken, path, argv, envp, mode);
|
||||||
if (vf && ret > 0)
|
if (vf && ret > 0)
|
||||||
{
|
{
|
||||||
|
debug_printf ("longjmping due to vfork");
|
||||||
vf->pid = ret;
|
vf->pid = ret;
|
||||||
longjmp (vf->j, 1);
|
longjmp (vf->j, 1);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user