From d5f4ee62b706f7cfe22a92fd796dc36382690950 Mon Sep 17 00:00:00 2001 From: Christopher Faylor Date: Mon, 26 Sep 2005 14:51:48 +0000 Subject: [PATCH] * exceptions.cc (handle_exceptions): Just si_code to SI_KERNEL first and let it be overridden. * exceptions.cc (_cygtls::call_signal_handler): Call signal handler with extra siginfo_t * and void * parameters when SA_SIGINFO flag is set. * signal.cc (signal): Clear SA_SIGINFO flag. (sigqueue): Fix incorrect setting of si_code. * sigproc.cc (signal_fixup_after_exec): Clear SA_SIGINFO flag when setting handler to SIG_DFL. --- winsup/cygwin/ChangeLog | 15 +++++++++++++++ winsup/cygwin/exceptions.cc | 15 ++++++++++----- winsup/cygwin/signal.cc | 7 ++++++- winsup/cygwin/sigproc.cc | 5 ++++- 4 files changed, 35 insertions(+), 7 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 4fc427ebe..368b984d6 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,18 @@ +2005-09-26 Christopher Faylor + + * exceptions.cc (handle_exceptions): Just si_code to SI_KERNEL first + and let it be overridden. + +2005-09-26 Yitzchak Scott-Thoennes + + * exceptions.cc (_cygtls::call_signal_handler): Call signal handler + with extra siginfo_t * and void * parameters when SA_SIGINFO flag is + set. + * signal.cc (signal): Clear SA_SIGINFO flag. + (sigqueue): Fix incorrect setting of si_code. + * sigproc.cc (signal_fixup_after_exec): Clear SA_SIGINFO flag when + setting handler to SIG_DFL. + 2005-09-26 Christopher Faylor * pinfo.cc (proc_waiter): Properly fill out si_code as according to SUSv3. diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc index bc0d31c7f..32d4b6d7e 100644 --- a/winsup/cygwin/exceptions.cc +++ b/winsup/cygwin/exceptions.cc @@ -424,6 +424,7 @@ handle_exceptions (EXCEPTION_RECORD *e0, void *frame, CONTEXT *in0, void *) CONTEXT in = *in0; siginfo_t si; + si.si_code = SI_KERNEL; /* Coerce win32 value to posix value. */ switch (e.ExceptionCode) { @@ -472,7 +473,6 @@ handle_exceptions (EXCEPTION_RECORD *e0, void *frame, CONTEXT *in0, void *) case STATUS_TIMEOUT: si.si_signo = SIGALRM; - si.si_code = 0; break; case STATUS_ACCESS_VIOLATION: @@ -489,7 +489,6 @@ handle_exceptions (EXCEPTION_RECORD *e0, void *frame, CONTEXT *in0, void *) case STATUS_CONTROL_C_EXIT: si.si_signo = SIGINT; - si.si_code = 0; break; case STATUS_INVALID_HANDLE: @@ -569,8 +568,6 @@ handle_exceptions (EXCEPTION_RECORD *e0, void *frame, CONTEXT *in0, void *) me.return_from_fault (); si.si_addr = ebp; - if (!si_code) - si.si_code = SI_KERNEL; si.si_errno = si.si_pid = si.si_uid = 0; me.push ((__stack_t) ebp, true); sig_send (NULL, si, &me); // Signal myself @@ -1253,7 +1250,15 @@ _cygtls::call_signal_handler () int this_errno = saved_errno; incyg--; sig = 0; - sigfunc (thissig); + if (this_sa_flags & SA_SIGINFO == 0) + sigfunc (thissig); + else + { + siginfo_t thissi = infodata; + void (*sigact) (int, siginfo_t *, void *) = (void (*) (int, siginfo_t *, void *)) func; + /* no ucontext_t information provided yet */ + sigact (thissig, &thissi, NULL); + } incyg++; set_signal_mask (this_oldmask, myself->getsigmask ()); if (this_errno >= 0) diff --git a/winsup/cygwin/signal.cc b/winsup/cygwin/signal.cc index 156fbec39..443d9ec6f 100644 --- a/winsup/cygwin/signal.cc +++ b/winsup/cygwin/signal.cc @@ -63,6 +63,7 @@ signal (int sig, _sig_func_ptr func) /* SA_RESTART is set to maintain BSD compatible signal behaviour by default. This is also compatible with the behaviour of signal(2) in Linux. */ global_sigs[sig].sa_flags |= SA_RESTART; + global_sigs[sig].sa_flags &= ~ SA_SIGINFO; set_sigcatchers (prev, func); syscall_printf ("%p = signal (%d, %p)", prev, sig, func); @@ -524,6 +525,10 @@ sigwaitinfo (const sigset_t *set, siginfo_t *info) return res; } +/* FIXME: SUSv3 says that this function should block until the signal has + actually been delivered. Currently, this will only happen when sending + signals to the current process. It will not happen when sending signals + to other processes. */ extern "C" int sigqueue (pid_t pid, int sig, const union sigval value) { @@ -535,7 +540,7 @@ sigqueue (pid_t pid, int sig, const union sigval value) return -1; } si.si_signo = sig; - si.si_code = SI_USER; + si.si_code = SI_QUEUE; si.si_pid = si.si_uid = si.si_errno = 0; si.si_value = value; return sig_send (dest, si); diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc index 7482bcbda..e27fccdd9 100644 --- a/winsup/cygwin/sigproc.cc +++ b/winsup/cygwin/sigproc.cc @@ -120,7 +120,10 @@ signal_fixup_after_exec () { global_sigs[i].sa_mask = 0; if (global_sigs[i].sa_handler != SIG_IGN) - global_sigs[i].sa_handler = SIG_DFL; + { + global_sigs[i].sa_handler = SIG_DFL; + global_sigs[i].sa_flags &= ~ SA_SIGINFO; + } } }