[C++] 纯文本查看 复制代码
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <setjmp.h>
#include <signal.h>
static volatile sig_atomic_t can_jump = 0;
void print_signal_set (FILE *of, char *prefix, const sigset_t *sigset)
{
int sig, cnt;
cnt = 0;
for (sig = 1; sig < NSIG; sig++) {
if (sigismember(sigset, sig)) {
cnt++;
fprintf(of, "%s%d (%s)\n", prefix, sig, strsignal(sig));
}
}
if (cnt == 0)
fprintf (of, "%s<empty signal set>\n", prefix);
}
int print_sigmask(FILE *of, const char *msg)
{
sigset_t curr_mask;
if (msg != NULL)
fprintf (of, "%s", msg);
if (sigprocmask(SIG_BLOCK, NULL, &curr_mask) == -1)
return -1;
print_signal_set(of, "\t\t", &curr_mask);
return 0;
}
#ifdef USE_SIGSETJMP
static sigjmp_buf senv;
#else
static jmp_buf env;
#endif
static void handler(int sig)
{
printf ("Received signal %d (%s), signal mask is:\n", sig, strsignal(sig));
print_sigmask (stdout, NULL);
if (!can_jump) {
printf ("'env' buffer not yet set, doing a simple return\n");
return;
}
#ifdef USE_SIGSETJMP
siglongjmp(senv, 1);
#else
longjmp(env, 1);
#endif
}
int main(int argc, char *argv[])
{
struct sigaction sa;
print_sigmask(stdout, "Sinal mask at startup:\n");
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
sa.sa_handler = handler;
if (sigaction(SIGINT, &sa, NULL) == -1) {
perror("sigaction");
exit (EXIT_FAILURE);
}
#ifdef USE_SIGSETJMP
printf ("Calling sigsetjmp()\n");
if (sigsetjmp(senv, 1) == 0)
#else
printf ("Calling setjmp()\n");
if (setjmp(env) == 0)
#endif
can_jump = 1;
else
print_sigmask(stdout, "After jump from handler, signal mask is:\n");
for(;;)
pause();
}