lib: do not mix declaration and code in external C code
[nit.git] / lib / signals / signals.nit.c
1 /* This file is part of NIT ( http://www.nitlanguage.org ).
2 *
3 * Copyright 2011 Alexis Laferrière <alexis.laf@xymus.net>
4 *
5 * This file is free software, which comes along with NIT. This software is
6 * distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
7 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
8 * PARTICULAR PURPOSE. You can modify it is you want, provided this header
9 * is kept unaltered, and a notification of the changes is added.
10 * You are allowed to redistribute it and sell it, alone or is a part of
11 * another product.
12 */
13
14 #undef _POSIX_SOURCE
15 #define _POSIX_SOURCE 1
16 #include <signal.h>
17 #include <stdio.h>
18
19 #include "signals.nit.h"
20
21 /*
22 Structure to manage each possible signals
23 are used in an array of 32 maximum signals.
24 This array is global to the software.
25 */
26 struct nit_signals_ent {
27 char raised; /* !=0 if has been raised */
28 SignalHandler handler; /* instance to receive call */
29 char safely; /* if !=0 then manage signal safely, otherwise react when raised */
30 } nit_signals_list[32] = {0x0};
31
32 /* Receiver to all signals
33 If unsafe, it calls directly the Nit receiver,
34 otherwise it marks the signal as raised and returns.
35 */
36 void receiver( int sig )
37 {
38 if ( sig < 32 && sig >=0 )
39 {
40 if ( nit_signals_list[sig].safely ) {
41 nit_signals_list[ sig ].raised += 1;
42 } else {
43 SignalHandler_receive_signal( nit_signals_list[ sig ].handler, sig );
44 }
45 }
46 }
47
48 /*
49 C implementation of signals::SignalHandler::handle_signal
50
51 Imported methods signatures:
52 void SignalHandler_receive_signal( SignalHandler recv, bigint signal ) for signals::SignalHandler::receive_signal
53 */
54 void SignalHandler_handle_signal___impl( SignalHandler recv, bigint signal, int safely )
55 {
56 SignalHandler last_handler;
57 if ( signal < 32 && signal >=0 ) {
58 struct sigaction act;
59 sigemptyset(&act.sa_mask);
60 act.sa_flags = 0;
61 act.sa_handler = receiver;
62
63 sigaction(signal, &act, NULL);
64
65 last_handler = nit_signals_list[signal].handler;
66 if ( last_handler != NULL )
67 SignalHandler_decr_ref( last_handler );
68
69 nit_signals_list[signal].handler = recv;
70 SignalHandler_incr_ref( recv );
71
72 nit_signals_list[signal].safely = safely;
73 }
74 }
75
76 /*
77 C implementation of signals::SignalHandler::ignore_signal
78 */
79 void SignalHandler_ignore_signal___impl( SignalHandler recv, bigint signal )
80 {
81 SignalHandler last_handler;
82 if ( signal < 32 && signal >=0 ) {
83 struct sigaction act;
84 sigemptyset(&act.sa_mask);
85 act.sa_flags = 0;
86 act.sa_handler = SIG_IGN;
87 sigaction(signal, &act, NULL);
88
89 last_handler = nit_signals_list[signal].handler;
90 if ( last_handler != NULL )
91 SignalHandler_decr_ref( last_handler );
92 }
93 }
94
95 /*
96 C implementation of signals::SignalHandler::default_signal
97 */
98 void SignalHandler_default_signal___impl( SignalHandler recv, bigint signal )
99 {
100 SignalHandler last_handler;
101 if ( signal < 32 && signal >=0 ) {
102 struct sigaction act;
103 sigemptyset(&act.sa_mask);
104 act.sa_flags = 0;
105 act.sa_handler = SIG_DFL;
106 sigaction(signal, &act, NULL);
107
108 last_handler = nit_signals_list[signal].handler;
109 if ( last_handler != NULL )
110 SignalHandler_decr_ref( last_handler );
111 }
112 }
113
114 void Object_set_alarm___impl( Object recv, bigint sec )
115 {
116 alarm( sec );
117 }
118
119 /*
120 C implementation of signals::Object::check_signals
121
122 Imported methods signatures:
123 void SignalHandler_receive_signal( SignalHandler recv, bigint signal ) for signals::SignalHandler::receive_signal
124 */
125 int Object_check_signals___impl( Object recv )
126 {
127 int sig;
128 int raised_something = 0;
129
130 for ( sig = 0; sig < 32; sig ++ )
131 if ( nit_signals_list[sig].raised ) {
132 nit_signals_list[sig].raised = 0;
133 raised_something = 1;
134 SignalHandler_receive_signal( nit_signals_list[sig].handler, sig );
135 }
136
137 return raised_something;
138 }