#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <setjmp.h>
#include <signal.h>
#include <err.h>
#include "../lpi.h"

void handler(int signo);
sigjmp_buf env;

int
main(int argc, char *argv[])
{
    int i, n, val;
    struct sigaction sa;

    n = 10;
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = 0;
    sa.sa_handler = handler;

    if (sigaction(SIGABRT, &sa, NULL) == -1)
        err(EXIT_FAILURE, "sigaction");

    printf("established a signal handler for SIGABRT\n");
    printf("this handler uses a nonlocal goto\n");

    if ((val = sigsetjmp(env, 1)) == 0) {
        printf("raise() %d SIGABRT\n", n);
        for (i = 0; i < n; i++) {
            printf("raised siganl SIGABRT #%d\n", i+1);
            raise(SIGABRT);
            sleep(1);
        }
    } else if (val == 1) {
        printf("control returned here in %dth SIGABRT signal\n", i+1);
        printf("now call abort()\n");
        abort();
    } else {
        printf("returned value from sigsetjmp()=%d\n", val);
    }

    printf("program ended successfully\n");
    exit(EXIT_SUCCESS);
}

void
handler(int signo)
{
    static sig_atomic_t val = 0;

    printf("caught signal %s\n", getSigname(signo));
    siglongjmp(env, ++val);
}
