chicken-users
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Chicken-users] replace signal with sigaction


From: Alan Post
Subject: [Chicken-users] replace signal with sigaction
Date: Thu, 29 Sep 2011 07:25:31 -0600

This patch replaces signal with sigaction for registering signals.
sigaction is a newer API for signal processing that fixes some
deficiencies of the original signal API.  One fix can be seen in
this patch: we don't have to reregister the signal handler after
a signal is sent.

That prevents a race condition whereby a signal is delivered, our
signal handler is reset, and before we can reregister our signal
handler, another signal is sent (which we then miss).

I'm not sure even signal() behaves this way these days.

It used to be one tested for sigaction in the same way you might
test for other features.  I'm not sure if chicken runs on a
platform that doesn't have sigaction--do I need to add a feature
test for this and preserve the existing capability on platforms
without sigaction?

-Alan

diff --git a/chicken.h b/chicken.h
index 1739fb9..4f5847a 100644
--- a/chicken.h
+++ b/chicken.h
@@ -859,7 +859,7 @@ DECL_C_PROC_p0 (128,  1,0,0,0,0,0,0,0)
 # define C_isatty                   isatty
 # define C_fileno                   fileno
 # define C_select                   select
-# define C_signal                   signal
+# define C_sigaction                sigaction
 # define C_getrusage                getrusage
 # define C_tolower                  tolower
 # define C_toupper                  toupper
diff --git a/runtime.c b/runtime.c
index 980f303..eb64f92 100644
--- a/runtime.c
+++ b/runtime.c
@@ -982,7 +982,6 @@ void initialize_symbol_table(void)
 void global_signal_handler(int signum)
 {
   C_raise_interrupt(signal_mapping_table[ signum ]);
-  signal(signum, global_signal_handler);
 }
 
 
@@ -4259,11 +4258,18 @@ C_regparm void C_fcall C_raise_interrupt(int reason)
 C_regparm C_word C_fcall C_establish_signal_handler(C_word signum, C_word 
reason)
 {
   int sig = C_unfix(signum);
+  struct sigaction new, old;
 
-  if(reason == C_SCHEME_FALSE) C_signal(sig, SIG_IGN);
-  else {
+  new.sa_flags = 0;
+  sigemptyset(&new.sa_mask);
+
+  if(reason == C_SCHEME_FALSE) {
+    new.sa_handler = SIG_IGN;
+    C_sigaction(sig, &new, &old);
+  } else {
     signal_mapping_table[ sig ] = C_unfix(reason);
-    C_signal(sig, global_signal_handler);
+    new.sa_handler = global_signal_handler;
+    C_sigaction(sig, &new, &old);
   }
 
   return C_SCHEME_UNDEFINED;
-- 
.i ma'a lo bradi cu penmi gi'e du



reply via email to

[Prev in Thread] Current Thread [Next in Thread]