diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index b5ce9988b..119b5e979 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,12 @@ +2005-12-22 Christopher Faylor + + * fork.cc (fork): Honor error return from sig_send. Don't continue + with fork if we couldn't suspend signals. + * sigproc.cc (sig_send): Set sigCONT event when we see __SIGNOHOLD. + (wait_sig): Remove holding_signals. Create pipe with a buffer which + will theoretically cause blocking if there is nothing reading on the + pipe. Wait for sigCONT at end of loop when we have a __SIGHOLD. + 2005-12-22 Corinna Vinschen * fhandler.h (fhandler_base::issymlink): New method. diff --git a/winsup/cygwin/fork.cc b/winsup/cygwin/fork.cc index 98ef42769..31a5820df 100644 --- a/winsup/cygwin/fork.cc +++ b/winsup/cygwin/fork.cc @@ -507,7 +507,14 @@ fork () return -1; } - sig_send (NULL, __SIGHOLD); + if (sig_send (NULL, __SIGHOLD)) + { + if (exit_state) + Sleep (INFINITE); + set_errno (EAGAIN); + return -1; + } + ischild = setjmp (grouped.ch.jmp); void *esp; diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc index 2e6542938..895d5b346 100644 --- a/winsup/cygwin/sigproc.cc +++ b/winsup/cygwin/sigproc.cc @@ -509,6 +509,8 @@ sigproc_terminate (exit_states es) int __stdcall sig_send (_pinfo *p, int sig) { + if (sig == __SIGNOHOLD) + SetEvent (sigCONT); siginfo_t si; si.si_signo = sig; si.si_code = SI_KERNEL; @@ -1046,12 +1048,11 @@ wait_sig (VOID *) { HANDLE readsig; PSECURITY_ATTRIBUTES sa_buf = (PSECURITY_ATTRIBUTES) alloca (1024); - Static bool holding_signals; /* Initialization */ SetThreadPriority (GetCurrentThread (), WAIT_SIG_PRIORITY); - if (!CreatePipe (&readsig, &myself->sendsig, sec_user_nih (sa_buf), 0)) + if (!CreatePipe (&readsig, &myself->sendsig, sec_user_nih (sa_buf), sizeof (sigpacket) - 4)) api_fatal ("couldn't create signal pipe, %E"); ProtectHandle (readsig); sigCONT = CreateEvent (&sec_none_nih, FALSE, FALSE, NULL); @@ -1121,11 +1122,9 @@ wait_sig (VOID *) *pack.mask |= bit; break; case __SIGHOLD: - holding_signals = 1; + goto loop; break; case __SIGNOHOLD: - holding_signals = 0; - /* fall through, intentionally */ case __SIGFLUSH: case __SIGFLUSHFAST: sigq.reset (); @@ -1144,8 +1143,6 @@ wait_sig (VOID *) default: if (pack.si.si_signo < 0) sig_clear (-pack.si.si_signo); - else if (holding_signals) - sigq.add (pack); else { int sig = pack.si.si_signo; @@ -1173,11 +1170,14 @@ wait_sig (VOID *) } if (clearwait) proc_subproc (PROC_CLEARWAIT, 0); + loop: if (pack.wakeup) { sigproc_printf ("signalling pack.wakeup %p", pack.wakeup); SetEvent (pack.wakeup); } + if (pack.si.si_signo == __SIGHOLD) + WaitForSingleObject (sigCONT, INFINITE); if (pack.si.si_signo == __SIGEXIT) break; }