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 * |