From 125205875b0b7daf8ab919387924a98b83d918b7 Mon Sep 17 00:00:00 2001 From: Christopher Faylor Date: Sun, 24 Jun 2001 21:57:50 +0000 Subject: [PATCH] * 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. --- winsup/cygwin/ChangeLog | 12 ++++ winsup/cygwin/exceptions.cc | 130 +++++++++++++++++------------------- winsup/cygwin/fork.cc | 4 +- winsup/cygwin/sigproc.cc | 2 +- winsup/cygwin/sigproc.h | 1 + winsup/cygwin/spawn.cc | 10 +-- 6 files changed, 84 insertions(+), 75 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 8dcfe7f50..11f7508fc 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,15 @@ +Sun Jun 24 17:38:19 2001 Christopher Faylor + + * 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 * fhandler.h class fhandler_socket): Declare new method diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc index 9ec179bea..cc69497b5 100644 --- a/winsup/cygwin/exceptions.cc +++ b/winsup/cygwin/exceptions.cc @@ -684,6 +684,10 @@ interrupt_setup (int sig, void *handler, DWORD retaddr, DWORD *retaddr_on_stack, myself->stopsig = 0; 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))); @@ -692,7 +696,7 @@ interrupt_now (CONTEXT *ctx, int sig, void *handler, struct sigaction& siga) { interrupt_setup (sig, handler, ctx->Eip, 0, siga); ctx->Eip = (DWORD) sigdelayed; - SetThreadContext (myself->getthread2signal (), ctx); /* Restart the thread */ + SetThreadContext (myself->getthread2signal (), ctx); /* Restart the thread in a new location */ return 1; } @@ -853,7 +857,9 @@ setup_handler (int sig, void *handler, struct sigaction& siga) } set_pending: - if (!interrupted) + if (interrupted) + res = 1; + else { pending_signals = 1; /* FIXME: Probably need to be more tricky here */ 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. */ 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) LeaveCriticalSection (&th->lock); @@ -1157,68 +1156,61 @@ void unused_sig_wrapper () to restore any mask, restores any potentially clobbered registers and returns to original caller. */ __asm__ volatile ("\n\ - .text\n\ -\n\ -_sigreturn:\n\ - addl $4,%%esp # Remove argument\n\ - movl %%esp,%%ebp\n\ - addl $36,%%ebp\n\ -\n\ - cmpl $0,%4 # Did a signal come in?\n\ - jz 1f # No, if zero\n\ - call _call_signal_handler_now@0 # yes handle the signal\n\ -\n\ -# FIXME: There is a race here. The signal handler could set up\n\ -# the sigsave structure between _call_signal_handler and the\n\ -# end of _set_process_mask. This would make cygwin detect an\n\ -# incorrect signal mask.\n\ -\n\ -1: call _set_process_mask@4\n\ - popl %%eax # saved errno\n\ - testl %%eax,%%eax # Is it < 0\n\ - jl 2f # yup. ignore it\n\ - movl %1,%%ebx\n\ - movl %%eax,(%%ebx)\n\ -2: popl %%eax\n\ - popl %%ebx\n\ - popl %%ecx\n\ - popl %%edx\n\ - popl %%edi\n\ - popl %%esi\n\ - popf\n\ - popl %%ebp\n\ - ret\n\ -\n\ -__no_sig_start:\n\ -_sigdelayed:\n\ - pushl %2 # original return address\n\ -_sigdelayed0:\n\ - pushl %%ebp\n\ - movl %%esp,%%ebp\n\ - pushf\n\ - pushl %%esi\n\ - pushl %%edi\n\ - pushl %%edx\n\ - pushl %%ecx\n\ - pushl %%ebx\n\ - pushl %%eax\n\ - pushl %7 # saved errno\n\ - pushl %3 # oldmask\n\ - pushl %4 # signal argument\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\ + .text \n\ +_sigreturn: \n\ + addl $4,%%esp # Remove argument \n\ + movl %%esp,%%ebp \n\ + addl $36,%%ebp \n\ + call _set_process_mask@4 \n\ + \n\ + cmpl $0,%4 # Did a signal come in? \n\ + jz 1f # No, if zero \n\ + call _call_signal_handler_now@0 # yes handle the signal \n\ + \n\ +1: popl %%eax # saved errno \n\ + testl %%eax,%%eax # Is it < 0 \n\ + jl 2f # yup. ignore it \n\ + movl %1,%%ebx \n\ + movl %%eax,(%%ebx) \n\ +2: popl %%eax \n\ + popl %%ebx \n\ + popl %%ecx \n\ + popl %%edx \n\ + popl %%edi \n\ + popl %%esi \n\ + popf \n\ + popl %%ebp \n\ + ret \n\ + \n\ +__no_sig_start: \n\ +_sigdelayed: \n\ + pushl %2 # original return address \n\ +_sigdelayed0: \n\ + pushl %%ebp \n\ + movl %%esp,%%ebp \n\ + pushf \n\ + pushl %%esi \n\ + pushl %%edi \n\ + pushl %%edx \n\ + pushl %%ecx \n\ + pushl %%ebx \n\ + pushl %%eax \n\ + pushl %7 # saved errno \n\ + pushl %3 # oldmask \n\ + pushl %4 # signal argument \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\ # that it is ok to set up sigsave\n\ -\n\ - call _set_process_mask@4\n\ - popl %%eax\n\ - jmp *%%eax\n\ -__no_sig_end:\n\ -\n\ + \n\ + call _set_process_mask@4 \n\ + popl %%eax \n\ + jmp *%%eax \n\ +__no_sig_end: \n\ " : "=m" (sigsave.sig) : "m" (&_impure_ptr->_errno), "g" (sigsave.retaddr), "g" (sigsave.oldmask), "g" (sigsave.sig), "g" (sigsave.func), "o" (pid_offset), "g" (sigsave.saved_errno), "g" (sigsave.newmask) diff --git a/winsup/cygwin/fork.cc b/winsup/cygwin/fork.cc index b44855497..ac9f855e9 100644 --- a/winsup/cygwin/fork.cc +++ b/winsup/cygwin/fork.cc @@ -708,7 +708,9 @@ vfork () for (pp = (char **)vf->frame, esp = vf->vfork_esp; esp <= vf->vfork_ebp + 1; 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 (); diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc index 64256508a..e70a51b3a 100644 --- a/winsup/cygwin/sigproc.cc +++ b/winsup/cygwin/sigproc.cc @@ -306,7 +306,7 @@ proc_subproc (DWORD what, DWORD val) zombies[nzombies] = pchildren[val]; // Add to zombie array 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); if ((int) val < --nchildren) { diff --git a/winsup/cygwin/sigproc.h b/winsup/cygwin/sigproc.h index a346094ac..5726a4519 100644 --- a/winsup/cygwin/sigproc.h +++ b/winsup/cygwin/sigproc.h @@ -96,6 +96,7 @@ extern HANDLE signal_arrived; BOOL __stdcall my_parent_is_alive (); extern "C" int __stdcall sig_dispatch_pending (int force = FALSE); extern "C" void __stdcall set_process_mask (sigset_t newmask); +extern "C" void __stdcall reset_signal_arrived (); int __stdcall sig_handle (int); void __stdcall sig_clear (int); void __stdcall sig_set_pending (int); diff --git a/winsup/cygwin/spawn.cc b/winsup/cygwin/spawn.cc index ccf9ed1f6..db2603e30 100644 --- a/winsup/cygwin/spawn.cc +++ b/winsup/cygwin/spawn.cc @@ -302,7 +302,7 @@ spawn_guts (HANDLE hToken, const char * prog_arg, const char *const *argv, return -1; } - syscall_printf ("spawn_guts (%.132s)", prog_arg); + syscall_printf ("spawn_guts (%d, %.132s)", mode, prog_arg); if (argv == NULL) { @@ -708,9 +708,9 @@ skip_arg_parsing: { /* These are both duplicated in the child code. We do this here, primarily for strace. */ - strcpy (myself->progname, real_path); strace.execing = 1; hExeced = pi.hProcess; + strcpy (myself->progname, real_path); } else { @@ -723,10 +723,10 @@ skip_arg_parsing: syscall_printf ("-1 = spawnve (), process table full"); return -1; } - child->progname[0] = '\0'; child->dwProcessId = pi.dwProcessId; child->hProcess = pi.hProcess; child.remember (); + strcpy (child->progname, real_path); /* Start the child running */ ResumeThread (pi.hThread); } @@ -761,7 +761,8 @@ skip_arg_parsing: break; case WAIT_OBJECT_0 + 1: sigproc_printf ("signal arrived"); - ResetEvent (signal_arrived); + // reset_signal_arrived (); + thisframe.call_signal_handler (); continue; case WAIT_OBJECT_0 + 2: 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); if (vf && ret > 0) { + debug_printf ("longjmping due to vfork"); vf->pid = ret; longjmp (vf->j, 1); }