From dcd0465b2b7d8693d6ba6a4225487b84ef5930a7 Mon Sep 17 00:00:00 2001 From: Christopher Faylor Date: Fri, 23 Dec 2005 22:50:20 +0000 Subject: [PATCH] * cygtls.cc (_cygtls::handle_threadlist_exception): Make an error fatal. * cygtls.h (sockaddr_in): Use header rather than defining our own structure. * exceptions.cc (_cygtls::interrupt_setup): Use exact contents of sa_mask rather than assuming tht current sig should be masked, too. (_cygtls::call_signal_handler): Use more aggressive locking. * gendef (_sigbe): Wait until later before releasing incyg. (_sigreturn): Remove more arguments to accommodate quasi-sa_sigaction support. (_sigdelayed): Push arguments for sa_sigaction. More work needed here. * signal.cc (sigaction): Implement SA_NODEFER. * tlsoffsets.h: Regenerate. * sigproc.cc (wait_sig): Use default buffer size of Windows 9x complains. * pinfo.cc (_onreturn::dummy_handle): Remove. (_onreturn::h): Make this a pointer. (_onreturn::~_onreturn): Detect whether pointer is NULL rather than value is NULL. (_onreturn::_onreturn): Set h to NULL initially. (_onreturn::no_close_p_handle): Set h to NULL. (winpids::add): Initialize onreturn with value from p.hProcess immediately. --- winsup/cygwin/ChangeLog | 25 +++++++++++++++++++++ winsup/cygwin/cygtls.cc | 2 +- winsup/cygwin/cygtls.h | 27 ++-------------------- winsup/cygwin/exceptions.cc | 14 ++++++------ winsup/cygwin/gendef | 16 ++++++++----- winsup/cygwin/libc/timelocal.cc | 2 +- winsup/cygwin/pinfo.cc | 29 +++++++++--------------- winsup/cygwin/regex/engine.c | 2 +- winsup/cygwin/regex/regex.7 | 2 +- winsup/cygwin/signal.cc | 22 +++++++++--------- winsup/cygwin/sigproc.cc | 2 +- winsup/cygwin/tlsoffsets.h | 40 ++++++++++++++++----------------- 12 files changed, 92 insertions(+), 91 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 119b5e979..78e8a32cd 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,28 @@ +2005-12-23 Christopher Faylor + + * cygtls.cc (_cygtls::handle_threadlist_exception): Make an error + fatal. + * cygtls.h (sockaddr_in): Use header rather than defining our own + structure. + * exceptions.cc (_cygtls::interrupt_setup): Use exact contents of + sa_mask rather than assuming tht current sig should be masked, too. + (_cygtls::call_signal_handler): Use more aggressive locking. + * gendef (_sigbe): Wait until later before releasing incyg. + (_sigreturn): Remove more arguments to accommodate quasi-sa_sigaction + support. + (_sigdelayed): Push arguments for sa_sigaction. More work needed here. + * signal.cc (sigaction): Implement SA_NODEFER. + * tlsoffsets.h: Regenerate. + + * sigproc.cc (wait_sig): Use default buffer size of Windows 9x complains. + + * pinfo.cc (_onreturn::dummy_handle): Remove. + (_onreturn::h): Make this a pointer. + (_onreturn::~_onreturn): Detect whether pointer is NULL rather than value is NULL. + (_onreturn::_onreturn): Set h to NULL initially. + (_onreturn::no_close_p_handle): Set h to NULL. + (winpids::add): Initialize onreturn with value from p.hProcess immediately. + 2005-12-22 Christopher Faylor * fork.cc (fork): Honor error return from sig_send. Don't continue diff --git a/winsup/cygwin/cygtls.cc b/winsup/cygwin/cygtls.cc index e8e846e54..03d177700 100644 --- a/winsup/cygwin/cygtls.cc +++ b/winsup/cygwin/cygtls.cc @@ -228,7 +228,7 @@ _cygtls::handle_threadlist_exception (EXCEPTION_RECORD *e, exception_list *frame sentry here; if (threadlist_ix == BAD_IX) { - system_printf ("called with threadlist_ix %d", BAD_IX); + api_fatal ("called with threadlist_ix %d", BAD_IX); return 1; } diff --git a/winsup/cygwin/cygtls.h b/winsup/cygwin/cygtls.h index 7ce70e04b..6feee64d0 100644 --- a/winsup/cygwin/cygtls.h +++ b/winsup/cygwin/cygtls.h @@ -18,31 +18,8 @@ details. */ #undef _NOMNTENT_FUNCS #include #include - #ifndef _WINSOCK_H -/* Stupid hack: Including winsock.h explicitly causes too many problems. */ -struct sockaddr_in -{ - short sin_family; - u_short sin_port; - struct in_addr - { - union - { - struct - { - u_char s_b1, s_b2, s_b3, s_b4; - } S_un_b; - struct - { - u_short s_w1, s_w2; - } S_un_w; - u_long S_addr; - } S_un; - }; - struct in_addr sin_addr; - char sin_zero[8]; -}; +#include typedef unsigned int SOCKET; #endif @@ -186,11 +163,11 @@ struct _cygtls san andreas; waitq wq; struct _cygtls *prev, *next; - __stack_t *stackptr; int sig; unsigned incyg; unsigned spinning; unsigned stacklock; + __stack_t *stackptr; __stack_t stack[TLS_STACK_SIZE]; unsigned padding[0]; diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc index 152210ff3..0b3ee022e 100644 --- a/winsup/cygwin/exceptions.cc +++ b/winsup/cygwin/exceptions.cc @@ -50,7 +50,7 @@ static size_t windows_system_directory_length; /* This is set to indicate that we have already exited. */ static NO_COPY int exit_already = 0; -static NO_COPY muto mask_sync; +static muto NO_COPY mask_sync; NO_COPY static struct { @@ -706,7 +706,7 @@ void __stdcall _cygtls::interrupt_setup (int sig, void *handler, struct sigaction& siga) { push ((__stack_t) sigdelayed); - deltamask = (siga.sa_mask | SIGTOMASK (sig)) & ~SIG_NONMASKABLE; + deltamask = siga.sa_mask & ~SIG_NONMASKABLE; sa_flags = siga.sa_flags; func = (void (*) (int)) handler; saved_errno = -1; // Flag: no errno to save @@ -982,8 +982,7 @@ sigrelse (int sig) return 0; } -/* Update the signal mask for this process - and return the old mask. +/* Update the signal mask for this process and return the old mask. Called from sigdelayed */ extern "C" sigset_t set_process_mask_delta () @@ -1253,7 +1252,7 @@ _cygtls::call_signal_handler () /* Call signal handler. */ while (sig) { - lock (); unlock (); // make sure synchronized + lock (); this_sa_flags = sa_flags; int thissig = sig; @@ -1261,8 +1260,9 @@ _cygtls::call_signal_handler () reset_signal_arrived (); sigset_t this_oldmask = set_process_mask_delta (); int this_errno = saved_errno; - incyg--; sig = 0; + unlock (); // make sure synchronized + incyg = 0; if (!(this_sa_flags & SA_SIGINFO)) { void (*sigfunc) (int) = func; @@ -1275,7 +1275,7 @@ _cygtls::call_signal_handler () /* no ucontext_t information provided yet */ sigact (thissig, &thissi, NULL); } - incyg++; + incyg = 1; set_signal_mask (this_oldmask, myself->getsigmask ()); if (this_errno >= 0) set_errno (this_errno); diff --git a/winsup/cygwin/gendef b/winsup/cygwin/gendef index 727d4bb5d..a81105c2f 100755 --- a/winsup/cygwin/gendef +++ b/winsup/cygwin/gendef @@ -132,9 +132,9 @@ __sigbe: # return here after cygwin syscall xorl %edx,%edx xchgl %edx,-4(%eax) # get return address from signal stack xchgl %edx,8(%esp) # restore edx/real return address - decl $tls::incyg(%ebx) decl $tls::stacklock(%ebx) # release lock popl %eax + decl $tls::incyg(%ebx) popl %ebx ret @@ -143,7 +143,7 @@ __sigbe: # return here after cygwin syscall _sigreturn: movl %fs:4,%ebx incl $tls::incyg(%ebx) - addl \$4,%esp # Remove argument + addl \$12,%esp # remove arguments call _set_process_mask\@4 1: movl \$1,%eax # potential lock value @@ -193,13 +193,19 @@ _sigdelayed: pushl $tls::saved_errno(%ebx) # saved errno call _set_process_mask_delta pushl %eax - pushl $tls::sig(%ebx) # signal argument - pushl \$_sigreturn + + # fill out handler arguments + xorl %eax,%eax # ucontext_t (currently not set) + pushl %eax + leal $tls::infodata(%ebx),%eax + pushl %eax # siginfo + pushl $tls::sig(%ebx) # signal number call _reset_signal_arrived\@0 + pushl \$_sigreturn # where to return pushl $tls::func(%ebx) # signal func cmpl \$0,$tls::threadkill(%ebx)#pthread_kill signal? - jnz 4f #yes. Callee clears signal number + jnz 4f # yes. callee clears signal number movl \$0,$tls::sig(%ebx) # zero the signal number as a # flag to the signal handler thread # that it is ok to set up sigsave diff --git a/winsup/cygwin/libc/timelocal.cc b/winsup/cygwin/libc/timelocal.cc index c268a2942..59a2e4155 100644 --- a/winsup/cygwin/libc/timelocal.cc +++ b/winsup/cygwin/libc/timelocal.cc @@ -81,7 +81,7 @@ static const struct lc_time_T _C_time_locale = { /* date_fmt */ "%a %b %e %H:%M:%S %Z %Y", - + /* alt_month * Standalone months forms for %OB */ diff --git a/winsup/cygwin/pinfo.cc b/winsup/cygwin/pinfo.cc index cc7cdbf78..47c2b7d0d 100644 --- a/winsup/cygwin/pinfo.cc +++ b/winsup/cygwin/pinfo.cc @@ -1091,27 +1091,23 @@ cygwin_winpid_to_pid (int winpid) #define size_pinfolist(i) (sizeof (pinfolist[0]) * ((i) + 1)) class _onreturn { - HANDLE& h; - HANDLE dummy_handle; + HANDLE *h; public: ~_onreturn () { if (h) { - CloseHandle (h); - h = NULL; + CloseHandle (*h); + *h = NULL; } } - void no_close_p_handle () {h = dummy_handle;} - _onreturn (): h (dummy_handle), dummy_handle (NULL) {} - void set (HANDLE& _h) {h = _h;} + void no_close_p_handle () {h = NULL;} + _onreturn (HANDLE& _h): h (&_h) {} }; inline void winpids::add (DWORD& nelem, bool winpid, DWORD pid) { - _onreturn onreturn; - bool perform_copy = make_copy; pid_t cygpid = cygwin_pid (pid); if (nelem >= npidlist) @@ -1126,23 +1122,18 @@ winpids::add (DWORD& nelem, bool winpid, DWORD pid) /* Open a the process to prevent a subsequent exit from invalidating the shared memory region. */ p.hProcess = OpenProcess (PROCESS_QUERY_INFORMATION, false, pid); - - p.init (cygpid, PID_NOREDIR | pinfo_access, NULL); + _onreturn onreturn (p.hProcess); /* If we couldn't open the process then we don't have rights to it and should make a copy of the shared memory area if it exists (it may not). - Otherwise, if p is "false" then we couldn't open the shared memory region - for the given pid, so close the handle to that process since we don't need to - protect this pid while the shared memory is open. - If p is true and we've opened the handle then things look good but we want - to track the handle to eventually close it if things fall apart subsequently. */ + bool perform_copy; if (!p.hProcess) perform_copy = true; - else if (!p) - CloseHandle (p.hProcess); else - onreturn.set (p.hProcess); + perform_copy = make_copy; + + p.init (cygpid, PID_NOREDIR | pinfo_access, NULL); /* If we're just looking for winpids then don't do any special cygwin "stuff* */ if (winpid) diff --git a/winsup/cygwin/regex/engine.c b/winsup/cygwin/regex/engine.c index 0b88dcf1e..42c91dc0f 100644 --- a/winsup/cygwin/regex/engine.c +++ b/winsup/cygwin/regex/engine.c @@ -956,7 +956,7 @@ FILE *d; fprintf(d, "\n"); } -/* +/* - at - print current situation == #ifdef REDEBUG == static void at(struct match *m, char *title, char *start, char *stop, \ diff --git a/winsup/cygwin/regex/regex.7 b/winsup/cygwin/regex/regex.7 index 0fa180269..dc53e8c47 100644 --- a/winsup/cygwin/regex/regex.7 +++ b/winsup/cygwin/regex/regex.7 @@ -93,7 +93,7 @@ or a collating-sequence name for either) enclosed in `[.' and `.]' stands for the sequence of characters of that collating element. The sequence is a single element of the bracket expression's list. -A bracket expression containing a multi-character collating element +A bracket expression containing a multi-character collating element can thus match more than one character, e.g. if the collating sequence includes a `ch' collating element, then the RE `[[.ch.]]*c' matches the first five characters diff --git a/winsup/cygwin/signal.cc b/winsup/cygwin/signal.cc index 01ba0bef0..09e8eee0e 100644 --- a/winsup/cygwin/signal.cc +++ b/winsup/cygwin/signal.cc @@ -257,6 +257,7 @@ killsys (pid_t pid, int sig) si.si_pid = si.si_uid = si.si_errno = 0; return kill0 (pid, si); } + int kill (pid_t pid, int sig) { @@ -356,28 +357,29 @@ sigaction (int sig, const struct sigaction *newact, struct sigaction *oldact) struct sigaction oa = global_sigs[sig]; - if (newact) - sigproc_printf ("signal %d, newact %p (handler %p), oa %p", sig, newact, newact->sa_handler, oa, oa.sa_handler); - else + if (!newact) sigproc_printf ("signal %d, newact %p, oa %p", sig, newact, oa, oa.sa_handler); - - if (newact) + else { + sigproc_printf ("signal %d, newact %p (handler %p), oa %p", sig, newact, newact->sa_handler, oa, oa.sa_handler); if (sig == SIGKILL || sig == SIGSTOP) { set_errno (EINVAL); return -1; } - global_sigs[sig] = *newact; - if (newact->sa_handler == SIG_IGN) + struct sigaction& na = global_sigs[sig]; + na = *newact; + if (!(na.sa_flags & SA_NODEFER)) + na.sa_mask |= SIGTOMASK(sig); + if (na.sa_handler == SIG_IGN) sig_clear (sig); - if (newact->sa_handler == SIG_DFL && sig == SIGCHLD) + if (na.sa_handler == SIG_DFL && sig == SIGCHLD) sig_clear (sig); - set_sigcatchers (oa.sa_handler, newact->sa_handler); + set_sigcatchers (oa.sa_handler, na.sa_handler); if (sig == SIGCHLD) { myself->process_state &= ~PID_NOCLDSTOP; - if (newact->sa_flags & SA_NOCLDSTOP) + if (na.sa_flags & SA_NOCLDSTOP) myself->process_state |= PID_NOCLDSTOP; } } diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc index 895d5b346..49b5eec87 100644 --- a/winsup/cygwin/sigproc.cc +++ b/winsup/cygwin/sigproc.cc @@ -1052,7 +1052,7 @@ wait_sig (VOID *) /* Initialization */ SetThreadPriority (GetCurrentThread (), WAIT_SIG_PRIORITY); - if (!CreatePipe (&readsig, &myself->sendsig, sec_user_nih (sa_buf), sizeof (sigpacket) - 4)) + if (!CreatePipe (&readsig, &myself->sendsig, sec_user_nih (sa_buf), 0)) api_fatal ("couldn't create signal pipe, %E"); ProtectHandle (readsig); sigCONT = CreateEvent (&sec_none_nih, FALSE, FALSE, NULL); diff --git a/winsup/cygwin/tlsoffsets.h b/winsup/cygwin/tlsoffsets.h index 4a00b2802..eebcfcaf0 100644 --- a/winsup/cygwin/tlsoffsets.h +++ b/winsup/cygwin/tlsoffsets.h @@ -47,16 +47,16 @@ //; $tls::pprev = 2944; //; $tls::next = -1048; //; $tls::pnext = 2948; -//; $tls::stackptr = -1044; -//; $tls::pstackptr = 2952; -//; $tls::sig = -1040; -//; $tls::psig = 2956; -//; $tls::incyg = -1036; -//; $tls::pincyg = 2960; -//; $tls::spinning = -1032; -//; $tls::pspinning = 2964; -//; $tls::stacklock = -1028; -//; $tls::pstacklock = 2968; +//; $tls::sig = -1044; +//; $tls::psig = 2952; +//; $tls::incyg = -1040; +//; $tls::pincyg = 2956; +//; $tls::spinning = -1036; +//; $tls::pspinning = 2960; +//; $tls::stacklock = -1032; +//; $tls::pstacklock = 2964; +//; $tls::stackptr = -1028; +//; $tls::pstackptr = 2968; //; $tls::stack = -1024; //; $tls::pstack = 2972; //; $tls::padding = 0; @@ -109,16 +109,16 @@ #define tls_pprev (2944) #define tls_next (-1048) #define tls_pnext (2948) -#define tls_stackptr (-1044) -#define tls_pstackptr (2952) -#define tls_sig (-1040) -#define tls_psig (2956) -#define tls_incyg (-1036) -#define tls_pincyg (2960) -#define tls_spinning (-1032) -#define tls_pspinning (2964) -#define tls_stacklock (-1028) -#define tls_pstacklock (2968) +#define tls_sig (-1044) +#define tls_psig (2952) +#define tls_incyg (-1040) +#define tls_pincyg (2956) +#define tls_spinning (-1036) +#define tls_pspinning (2960) +#define tls_stacklock (-1032) +#define tls_pstacklock (2964) +#define tls_stackptr (-1028) +#define tls_pstackptr (2968) #define tls_stack (-1024) #define tls_pstack (2972) #define tls_padding (0)