Merge: Nitsmell : Adding new code smells and print console updated
[nit.git] / lib / signals.nit
index d704d3f..351807d 100644 (file)
@@ -14,7 +14,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-# Module to manage standard C signals
+# ANSI C signal handling
 #
 # Common usage imply 5 steps:
 #
@@ -64,6 +64,7 @@ module signals
        #define _POSIX_SOURCE 1
        #include <signal.h>
        #include <stdio.h>
+       #include <unistd.h>
 
        /*
        */
@@ -78,7 +79,7 @@ module signals
                char raised; /* !=0 if has been raised */
                void* handler; /* instance to receive call */
                char safely; /* if !=0 then manage signal safely, otherwise react when raised */
-       } nit_signals_list[32] = {0x0};
+       } nit_signals_list[32] = {{0}};
 
        /* Receiver to all signals
                If unsafe, it calls directly the Nit receiver,
@@ -107,10 +108,10 @@ interface SignalHandler
        #
        #     class MyReceiver
        #         super SignalHandler
-       #     
+       #
        #         redef fun receive_signal(signal) do print "received safely {signal}"
        #     end
-       #     
+       #
        #     var r = new MyReceiver
        #     r.handle_signal(sigint, true) # will call back when "check_signals" is called
        #     # ...
@@ -127,10 +128,10 @@ interface SignalHandler
        #
        #     class MyReceiver
        #         super SignalHandler
-       #     
+       #
        #         redef fun receive_signal_unsafe(signal) do print "received unsafely {signal}"
        #     end
-       #     
+       #
        #     var r = new MyReceiver
        #     r.handle_signal(sigsegv, false) # `r.receive_signal_unsafe` will be invoked on sigsegv
        fun receive_signal_unsafe(signal: Int) do end
@@ -140,9 +141,7 @@ interface SignalHandler
        # If `safely`, receiver will be called when `check_signals` in invoked
        # otherwise the receiver is invoked when the signal is raised, it may
        # crash the Nit system but is unavoidable for unstoppable signals.
-       fun handle_signal(signal: Int, safely: Bool) import
-               receive_signal `{
-               SignalHandler last_handler;
+       fun handle_signal(signal: Int, safely: Bool) import receive_signal `{
                if (signal < 32 && signal >=0) {
                        struct sigaction act;
                        sigemptyset(&act.sa_mask);
@@ -151,21 +150,27 @@ interface SignalHandler
 
                        sigaction(signal, &act, NULL);
 
-                       last_handler = (SignalHandler)nit_signals_list[signal].handler;
+               #ifdef SignalHandler_decr_ref
+                       SignalHandler last_handler = (SignalHandler)nit_signals_list[signal].handler;
                        if (last_handler != NULL)
                                SignalHandler_decr_ref(last_handler);
+               #endif
 
                        nit_signals_list[signal].handler = self;
+
+               #ifdef SignalHandler_incr_ref
                        SignalHandler_incr_ref(self);
+               #endif
 
                        nit_signals_list[signal].safely = safely;
-                       nit_SignalHandler_receive_signal = SignalHandler_receive_signal;
+
+                       nit_SignalHandler_receive_signal =
+                               (void (*)(void*, long))&SignalHandler_receive_signal;
                }
        `}
 
        # Set to ignore the signal
        fun ignore_signal(signal: Int) `{
-               SignalHandler last_handler;
                if (signal < 32 && signal >=0) {
                        struct sigaction act;
                        sigemptyset(&act.sa_mask);
@@ -173,15 +178,16 @@ interface SignalHandler
                        act.sa_handler = SIG_IGN;
                        sigaction(signal, &act, NULL);
 
-                       last_handler = (SignalHandler)nit_signals_list[signal].handler;
+               #ifdef SignalHandler_decr_ref
+                       SignalHandler last_handler = (SignalHandler)nit_signals_list[signal].handler;
                        if (last_handler != NULL)
                                SignalHandler_decr_ref(last_handler);
+               #endif
                }
        `}
 
        # Set default action for the signal
        fun default_signal(signal: Int) `{
-               SignalHandler last_handler;
                if (signal < 32 && signal >=0) {
                        struct sigaction act;
                        sigemptyset(&act.sa_mask);
@@ -189,37 +195,36 @@ interface SignalHandler
                        act.sa_handler = SIG_DFL;
                        sigaction(signal, &act, NULL);
 
-                       last_handler = (SignalHandler)nit_signals_list[signal].handler;
+               #ifdef SignalHandler_decr_ref
+                       SignalHandler last_handler = (SignalHandler)nit_signals_list[signal].handler;
                        if (last_handler != NULL)
                                SignalHandler_decr_ref(last_handler);
+               #endif
                }
        `}
 end
 
-redef interface Object
-
-       # Check signals for safe operation
-       # will callback receiver of raised signals
-       # can callback any instance of SignalHandler, not just this one
-       protected fun check_signals: Bool is extern import SignalHandler.receive_signal `{
-               int sig;
-               int raised_something = 0;
-
-               for (sig = 0; sig < 32; sig ++)
-                       if (nit_signals_list[sig].raised) {
-                               nit_signals_list[sig].raised = 0;
-                               raised_something = 1;
-                               SignalHandler handler = (SignalHandler)nit_signals_list[sig].handler;
-                               SignalHandler_receive_signal(handler, sig);
-                       }
+# Check signals for safe operation
+# will callback receiver of raised signals
+# can callback any instance of SignalHandler, not just this one
+fun check_signals: Bool is extern import SignalHandler.receive_signal `{
+       int sig;
+       int raised_something = 0;
+
+       for (sig = 0; sig < 32; sig ++)
+               if (nit_signals_list[sig].raised) {
+                       nit_signals_list[sig].raised = 0;
+                       raised_something = 1;
+                       SignalHandler handler = (SignalHandler)nit_signals_list[sig].handler;
+                       SignalHandler_receive_signal(handler, sig);
+               }
 
-               return raised_something;
-       `}
+       return raised_something;
+`}
 
-       # Set alarm signal
-       # can callback any instance of SignalHandler, not just this one
-       protected fun set_alarm(sec: Int) `{ alarm(sec); `}
-end
+# Set alarm signal
+# can callback any instance of SignalHandler, not just this one
+fun set_alarm(sec: Int) `{ alarm(sec); `}
 
 redef class Process
        # Send a signal to the process
@@ -227,7 +232,7 @@ redef class Process
 
        # Send the kill signal to the process
        fun kill do signal(sigkill)
-       
+
        # Native implementation of `signal`
        private fun native_kill(pid, signal: Int) `{ kill(pid, signal); `}
 end
@@ -304,7 +309,7 @@ fun sigvtalrm: Int do return 26
 # Profiling timer expired
 fun sigprof: Int do return 27
 
-# Sent to a process when its controlling terminal changes its window size 
+# Sent to a process when its controlling terminal changes its window size
 fun sigwinch: Int do return 28
 
 # Sent to a process when the system experiences a power failure