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 *