use 3-arg signal handlers when SA_SIGINFO flag is set

Yitzchak Scott-Thoennes sthoenna@efn.org
Mon Sep 26 04:27:00 GMT 2005


I've done some but not a lot of testing with this patch.  In
particular, I'm not sure that the tls field infodata always is set for
all kinds of signals.

Given that cygwin doesn't even have a ucontext.h header,
I don't think sending the third parameter to signal handlers as
NULL is a bad thing; presumably any code that actually uses it
would fail to compile on cygwin.

In exceptions.cc handle_exceptions, si_sigval is being set to
various things that should be put in si_code instead (and
si_code is set to SI_KERNEL).  I haven't changed this yet, and
would appreciate someone else confirming that it should change
(or explaining why it shouldn't).

2005-08-01  Yitzchak Scott-Thoennes  <sthoenna@efn.org>

	* 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): Set SI_QUEUE code in siginfo_t struct.
	* sigproc.cc (signal_fixup_after_exec): Clear SA_SIGINFO
	flag when setting handler to SIG_DFL.

--- exceptions.cc.orig	2005-09-25 02:07:39.346110000 -0700
+++ exceptions.cc	2005-09-25 18:23:48.975100800 -0700
@@ -1245,6 +1245,7 @@ _cygtls::call_signal_handler ()
       this_sa_flags = sa_flags;
       int thissig = sig;
       void (*sigfunc) (int) = func;
+      siginfo_t thissi = infodata;
 
       pop ();
       reset_signal_arrived ();
@@ -1252,7 +1253,13 @@ _cygtls::call_signal_handler ()
       int this_errno = saved_errno;
       incyg--;
       sig = 0;
-      sigfunc (thissig);
+      if (this_sa_flags & SA_SIGINFO == 0) sigfunc (thissig);
+      else
+        {
+          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)
--- signal.cc.orig	2005-09-25 02:09:35.673380000 -0700
+++ signal.cc	2005-09-25 21:02:55.582448000 -0700
@@ -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);
@@ -535,7 +536,7 @@ sigqueue (pid_t pid, int sig, const unio
       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);
--- sigproc.cc.orig	2005-09-25 02:09:39.739227000 -0700
+++ sigproc.cc	2005-09-25 18:07:23.888616000 -0700
@@ -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;
+	}
     }
 }
 



More information about the Cygwin-patches mailing list