#include #include #include "structs.h" #include "signals.h" typedef struct stk STK; struct stk { STK *link; JMP *j; } ; static volatile int interrupt_count = 1; static STK * volatile stack; static sigset_t mask_sigs; static volatile int int_blocked; static volatile int while_blocked; static void sigint(int sig __attribute__((__unused__))) { STK *s; if (int_blocked) { while_blocked = 1; return; } interrupt_count ++; s = stack; if (s && s->j) longjmp(s->j->b,1); } void initsignals(void) { struct sigaction sa; int_blocked = 0; while_blocked = 0; sigemptyset(&mask_sigs); sigaddset(&mask_sigs,SIGINT); stack = 0; sa.sa_handler = &sigint; sigemptyset(&sa.sa_mask); sa.sa_flags = SA_RESTART; sigaction(SIGINT,&sa,0); } int interrupted(void) { return(interrupt_count); } void push_sigint_throw(JMP *j) { STK *s; sigset_t m; sigemptyset(&m); sigprocmask(SIG_BLOCK,&mask_sigs,&m); s = malloc(sizeof(STK)); *(volatile STK *)s = (STK){ .j = j, .link = stack }; stack = s; sigprocmask(SIG_SETMASK,&m,0); } void pop_sigint_throw(void) { STK *s; sigset_t m; sigemptyset(&m); sigprocmask(SIG_BLOCK,&mask_sigs,&m); s = stack; stack = s->link; free(s); sigprocmask(SIG_SETMASK,&m,0); } void block_int(void) { while_blocked = 0; int_blocked = 1; } void unblock_int(void) { int_blocked = 0; if (while_blocked) sigint(SIGINT); }