util-src/signal.c
changeset 8417 7ea3311ca632
parent 7976 703f7f45feb4
child 8423 fb27aff6d491
equal deleted inserted replaced
8414:a9e8523a5e73 8417:7ea3311ca632
    47 	int sig; /* the signal */
    47 	int sig; /* the signal */
    48 };
    48 };
    49 
    49 
    50 #endif
    50 #endif
    51 
    51 
       
    52 #define MAX_PENDING_SIGNALS 32
       
    53 
    52 #define LUA_SIGNAL "lua_signal"
    54 #define LUA_SIGNAL "lua_signal"
    53 
    55 
    54 static const struct lua_signal lua_signals[] = {
    56 static const struct lua_signal lua_signals[] = {
    55 	/* ANSI C signals */
    57 	/* ANSI C signals */
    56 #ifdef SIGABRT
    58 #ifdef SIGABRT
   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]])