[INTERPRETER]

* BUG: Disable debugging messages from signal management routines.

[GB.SIGNAL]
* NEW: Call previous signal handlers automatically when a specific signal 
  is catched.


git-svn-id: svn://localhost/gambas/trunk@4722 867c0c6c-44f3-4631-809d-bfa615b0a4ec
This commit is contained in:
Benoît Minisini 2012-05-08 17:15:54 +00:00
parent 30f9a40f2b
commit 4afe7caf6b
2 changed files with 45 additions and 4 deletions

View file

@ -28,6 +28,8 @@
#include "gbx_api.h"
#include "gbx_signal.h"
//#define DEBUG_ME 1
static SIGNAL_HANDLER *_handlers = NULL;
static int _pipe[2];
static int _count = 0;
@ -36,8 +38,10 @@ void SIGNAL_install(SIGNAL_HANDLER *handler, int signum, void (*callback)(int, s
{
struct sigaction action;
#ifdef DEBUG_ME
fprintf(stderr, "SIGNAL_install: %d %p\n", signum, callback);
#endif
handler->signum = signum;
action.sa_flags = SA_SIGINFO;
@ -50,8 +54,10 @@ void SIGNAL_install(SIGNAL_HANDLER *handler, int signum, void (*callback)(int, s
void SIGNAL_uninstall(SIGNAL_HANDLER *handler, int signum)
{
#ifdef DEBUG_ME
fprintf(stderr, "SIGNAL_uninstall: %d\n", signum);
#endif
while (handler->callbacks)
SIGNAL_unregister(handler->signum, handler->callbacks);
@ -172,7 +178,9 @@ SIGNAL_CALLBACK *SIGNAL_register(int signum, void (*callback)(int, intptr_t), in
cb->callback = callback;
cb->data = data;
#ifdef DEBUG_ME
fprintf(stderr, "SIGNAL_register: %d -> %p\n", signum, cb);
#endif
return cb;
}
@ -193,7 +201,9 @@ void SIGNAL_unregister(int signum, SIGNAL_CALLBACK *cb)
if (cb == handler->callbacks)
handler->callbacks = cb->next;
#ifdef DEBUG_ME
fprintf(stderr, "SIGNAL_unregister: %d %p\n", signum, cb);
#endif
FREE(&cb, "SIGNAL_unregister_callback");

View file

@ -182,9 +182,40 @@ static void add_handler(int num, struct sigaction *action)
static void handle_signal(int num, siginfo_t *info, void *context)
{
SIGNAL_HANDLER *sh;
char cnum = (char)num;
if (write(_pipe_signal[1], &cnum, 1) != 1)
return;
int save_errno;
save_errno = errno;
for(;;)
{
if (write(_pipe_signal[1], &cnum, 1) == 1)
break;
if (errno != EINTR)
break;
}
// Call old signal handler
sh = find_handler(num);
if (sh->action.sa_handler != SIG_DFL && sh->action.sa_handler != SIG_IGN)
{
if (sh->action.sa_flags & SA_SIGINFO)
{
//fprintf(stderr, "Calling old action %p\n", _old_SIGCHLD_action.sa_sigaction);
(*sh->action.sa_sigaction)(num, info, context);
}
else
{
//fprintf(stderr, "Calling old handler %p\n", _old_SIGCHLD_action.sa_handler);
(*sh->action.sa_handler)(num);
}
}
errno = save_errno;
}
BEGIN_METHOD_VOID(Signal_Reset)