Software /
code /
prosody
Comparison
util-src/signal.c @ 2430:69d377c84fe3
util.signal: Queue up multiple signals, instead of trampling on the previous debug hook (and never clearing our own)
author | Matthew Wild <mwild1@gmail.com> |
---|---|
date | Sun, 10 Jan 2010 00:28:48 +0000 |
parent | 2405:88f73ee1c46f |
child | 2431:c4d32b35fe60 |
comparison
equal
deleted
inserted
replaced
2429:5cfa1400e247 | 2430:69d377c84fe3 |
---|---|
25 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | 25 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
26 * OTHER DEALINGS IN THE SOFTWARE. | 26 * OTHER DEALINGS IN THE SOFTWARE. |
27 */ | 27 */ |
28 | 28 |
29 #include <signal.h> | 29 #include <signal.h> |
30 #include <malloc.h> | |
30 | 31 |
31 #include "lua.h" | 32 #include "lua.h" |
32 #include "lauxlib.h" | 33 #include "lauxlib.h" |
33 | 34 |
34 #ifndef lsig | 35 #ifndef lsig |
147 {"SIGSYS", SIGSYS}, | 148 {"SIGSYS", SIGSYS}, |
148 #endif | 149 #endif |
149 {NULL, 0} | 150 {NULL, 0} |
150 }; | 151 }; |
151 | 152 |
152 static int Nsig = 0; | |
153 static lua_State *Lsig = NULL; | 153 static lua_State *Lsig = NULL; |
154 static lua_Hook Hsig = NULL; | 154 static lua_Hook Hsig = NULL; |
155 static int Hmask = 0; | 155 static int Hmask = 0; |
156 static int Hcount = 0; | 156 static int Hcount = 0; |
157 | 157 |
158 static struct signal_event | |
159 { | |
160 int Nsig; | |
161 struct signal_event *next_event; | |
162 } *signal_queue = NULL; | |
163 | |
164 static struct signal_event *last_event = NULL; | |
165 | |
158 static void sighook(lua_State *L, lua_Debug *ar) | 166 static void sighook(lua_State *L, lua_Debug *ar) |
159 { | 167 { |
160 lua_pushstring(L, LUA_SIGNAL); | 168 lua_pushstring(L, LUA_SIGNAL); |
161 lua_gettable(L, LUA_REGISTRYINDEX); | 169 lua_gettable(L, LUA_REGISTRYINDEX); |
162 lua_pushnumber(L, Nsig); | 170 |
163 lua_gettable(L, -2); | 171 struct signal_event *event; |
164 | 172 while((event = signal_queue)) |
165 lua_call(L, 0, 0); | 173 { |
166 | 174 lua_pushnumber(L, event->Nsig); |
167 /* set the old hook */ | 175 lua_gettable(L, -2); |
176 lua_call(L, 0, 0); | |
177 signal_queue = event->next_event; | |
178 free(event); | |
179 }; | |
180 | |
181 lua_pop(L, 1); /* pop lua_signal table */ | |
182 | |
183 /* restore the old hook */ | |
168 lua_sethook(L, Hsig, Hmask, Hcount); | 184 lua_sethook(L, Hsig, Hmask, Hcount); |
169 } | 185 } |
170 | 186 |
171 static void handle(int sig) | 187 static void handle(int sig) |
172 { | 188 { |
173 Hsig = lua_gethook(Lsig); | 189 if(!signal_queue) |
174 Hmask = lua_gethookmask(Lsig); | 190 { |
175 Hcount = lua_gethookcount(Lsig); | 191 /* Store the existing debug hook (if any) and its parameters */ |
176 Nsig = sig; | 192 Hsig = lua_gethook(Lsig); |
177 | 193 Hmask = lua_gethookmask(Lsig); |
178 lua_sethook(Lsig, sighook, LUA_MASKCALL | LUA_MASKRET | LUA_MASKCOUNT, 1); | 194 Hcount = lua_gethookcount(Lsig); |
179 /* | 195 |
180 switch (sig) | 196 signal_queue = malloc(sizeof(struct signal_event)); |
181 { | 197 signal_queue->Nsig = sig; |
182 case SIGABRT: ; | 198 signal_queue->next_event = NULL; |
183 case SIGFPE: ; | 199 |
184 case SIGILL: ; | 200 last_event = signal_queue; |
185 case SIGINT: ; | 201 |
186 case SIGSEGV: ; | 202 /* Set our new debug hook */ |
187 case SIGTERM: ; | 203 lua_sethook(Lsig, sighook, LUA_MASKCALL | LUA_MASKRET | LUA_MASKCOUNT, 1); |
188 } */ | 204 } |
205 else | |
206 { | |
207 last_event->next_event = malloc(sizeof(struct signal_event)); | |
208 last_event->next_event->Nsig = sig; | |
209 last_event->next_event->next_event = NULL; | |
210 | |
211 last_event = last_event->next_event; | |
212 } | |
189 } | 213 } |
190 | 214 |
191 /* | 215 /* |
192 * l_signal == signal(signal [, func [, chook]]) | 216 * l_signal == signal(signal [, func [, chook]]) |
193 * | 217 * |