158 static lua_State *Lsig = NULL; |
160 static lua_State *Lsig = NULL; |
159 static lua_Hook Hsig = NULL; |
161 static lua_Hook Hsig = NULL; |
160 static int Hmask = 0; |
162 static int Hmask = 0; |
161 static int Hcount = 0; |
163 static int Hcount = 0; |
162 |
164 |
163 static struct signal_event { |
165 int signals[MAX_PENDING_SIGNALS]; |
164 int Nsig; |
166 int nsig = 0; |
165 struct signal_event *next_event; |
|
166 } *signal_queue = NULL; |
|
167 |
|
168 static struct signal_event *last_event = NULL; |
|
169 |
167 |
170 static void sighook(lua_State *L, lua_Debug *ar) { |
168 static void sighook(lua_State *L, lua_Debug *ar) { |
171 struct signal_event *event; |
|
172 /* restore the old hook */ |
169 /* restore the old hook */ |
173 lua_sethook(L, Hsig, Hmask, Hcount); |
170 lua_sethook(L, Hsig, Hmask, Hcount); |
174 |
171 |
175 lua_pushstring(L, LUA_SIGNAL); |
172 lua_pushstring(L, LUA_SIGNAL); |
176 lua_gettable(L, LUA_REGISTRYINDEX); |
173 lua_gettable(L, LUA_REGISTRYINDEX); |
177 |
174 |
178 while((event = signal_queue)) { |
175 for(int i = 1; i <= nsig; i--) { |
179 lua_pushnumber(L, event->Nsig); |
176 lua_pushnumber(L, signals[i]); |
180 lua_gettable(L, -2); |
177 lua_gettable(L, -2); |
181 lua_call(L, 0, 0); |
178 lua_call(L, 0, 0); |
182 signal_queue = event->next_event; |
|
183 free(event); |
|
184 }; |
179 }; |
185 |
180 |
|
181 nsig = 0; |
|
182 |
186 lua_pop(L, 1); /* pop lua_signal table */ |
183 lua_pop(L, 1); /* pop lua_signal table */ |
187 |
184 |
188 } |
185 } |
189 |
186 |
190 static void handle(int sig) { |
187 static void handle(int sig) { |
191 if(!signal_queue) { |
188 if(nsig == 0) { |
192 /* Store the existing debug hook (if any) and its parameters */ |
189 /* Store the existing debug hook (if any) and its parameters */ |
193 Hsig = lua_gethook(Lsig); |
190 Hsig = lua_gethook(Lsig); |
194 Hmask = lua_gethookmask(Lsig); |
191 Hmask = lua_gethookmask(Lsig); |
195 Hcount = lua_gethookcount(Lsig); |
192 Hcount = lua_gethookcount(Lsig); |
196 |
193 |
197 signal_queue = malloc(sizeof(struct signal_event)); |
|
198 signal_queue->Nsig = sig; |
|
199 signal_queue->next_event = NULL; |
|
200 |
|
201 last_event = signal_queue; |
|
202 |
|
203 /* Set our new debug hook */ |
194 /* Set our new debug hook */ |
204 lua_sethook(Lsig, sighook, LUA_MASKCALL | LUA_MASKRET | LUA_MASKCOUNT, 1); |
195 lua_sethook(Lsig, sighook, LUA_MASKCALL | LUA_MASKRET | LUA_MASKCOUNT, 1); |
205 } else { |
196 } |
206 last_event->next_event = malloc(sizeof(struct signal_event)); |
197 |
207 last_event->next_event->Nsig = sig; |
198 if(nsig < MAX_PENDING_SIGNALS) { |
208 last_event->next_event->next_event = NULL; |
199 signals[++nsig] = sig; |
209 |
|
210 last_event = last_event->next_event; |
|
211 } |
200 } |
212 } |
201 } |
213 |
202 |
214 /* |
203 /* |
215 * l_signal == signal(signal [, func [, chook]]) |
204 * l_signal == signal(signal [, func [, chook]]) |