Chapter Contents |
Previous |
Next |
sigsetjmp |
Portability: | POSIX.1 conforming |
SYNOPSIS | |
DESCRIPTION | |
RETURN VALUE | |
IMPLEMENTATION | |
EXAMPLE | |
RELATED FUNCTIONS | |
SEE ALSO |
SYNOPSIS |
#include <lcjmp.h> int sigsetjmp(sigjmp_buf env, int savemask);
The synopsis for the POSIX implementation is
#include <setjmp.h> int sigsetjmp(sigjmp_buf env, int savemask);
You should use
<setjmp.h>
only if an appropriate feature test macro has been defined.
DESCRIPTION |
sigsetjmp
saves the current stack environment and signal mask.
env
is a pointer to the
sigjmp_buf
structure that contains the current environment.
savemask
specifies whether or not the signal mask is saved; if
savemask
is 0, the current signal mask is not
saved. A nonzero value specifies that the current signal mask is saved.
See blkjmp for more information on saving the
signal mask as a part of a setjmp
operation and restoring it as part of a longjmp operation.
RETURN VALUE |
sigsetjmp
returns the value 0, or the value specified in the call to
siglongjmp
.
IMPLEMENTATION |
sigsetjmp
is defined as a macro and should not be used with
#undef
.
EXAMPLE |
The following example is an outline of
an application using
sigsetjmp
and
siglongjmp
for error recovery. The program is
designed so that if a protection exception (
SIGSEGV
) occurs, control is returned using
siglongjmp
to any of several locations, depending on when the error occurred.
The signal mask at the time of the exception may differ from the signal mask
of the cleanup code, which is unknown.
/* This example must be compiled with the posix */ /* compiler option. */ #include <sys/types.h> #include <signal.h> #include <setjmp.h> #include <stdio.h> #include <unistd.h> #include <lclib.h> /* This is the address of a sigjmp buffer defining */ /* the SIGSEGV */ /* recovery location. */ sigjmp_buf *recover; extern void reinit(void); extern void fixfiles(void); extern void int_handler(int); /* SIGINT handler - not shown */ extern void alrm_handler(int); /* SIGALRM handler - not shown*/ extern void term_handler(int); /* SIGTERM handler - not shown*/ static void segv_handler(int); /* SIGSEGV handler */ /* shutdown flag, set by SIGTERM handler */ int shutdown = 0; main() { sigjmp_buf mainbuf; struct sigaction int_action, alrm_action, segv_action; sigset_t newmask, oldmask; /* This code defines the normal recovery action, which */ /* is to reinitialize the program. No signals are */ /* masked at this point. */ */ if (sigsetjmp(mainbuf, 1)) { /* if a SIGSEGV occurred */ fputs("SIGSEGV error, reinitializing...", stderr); fflush(stderr); reinit(); } recover = &mainbuf; /* Save recovery buffer. */ /* Define signal actions. */ segv_action.sa_handler = &segv_handler; segv_action.sa_flags = 0; /* Block SIGINT, SIGALRM and SIGTERM while we're */ /* handling SIGSEGV. */ sigemptyset(&segv_action.sa_mask); sigaddset(&segv_action.sa_mask, SIGINT); sigaddset(&segv_action.sa_mask, SIGALRM); sigaddset(&segv_action.sa_mask, SIGTERM); sigaction(SIGSEGV, &segv_action, NULL); alrm_action.sa_handler = &alrm_handler; alrm_action.sa_flags = 0; /* Block SIGINT while we're handling SIGALRM. */ sigemptyset(&alrm_action.sa_mask); sigaddset(&alrm_action.sa_mask, SIGINT); sigaction(SIGALRM, &alrm_action, NULL); int_action.sa_handler = &int_handler; int_action.sa_flags = 0; /* Block SIGALRM while we're handling SIGINT. */ sigemptyset(&int_action.sa_mask); sigaddset(&int_action.sa_mask, SIGALRM); sigaction(SIGINT, &int_action, NULL); term_action.sa_handler = &term_handler; term_action.sa_flags = 0; /* Only SIGTERM is blocked in the SIGTERM handler. */ sigemptyset(&term_action.sa_mask); sigaction(SIGTERM, &term_action, NULL); sigemptyset(&newmask); /* Set up mask to block SIGINT + SIGALRM. */ sigaddset(&newmask, SIGINT); sigaddset(&newmask, SIGALRM); alarm(5); /* Perform checkpoint every 5 seconds. */ while(!shutdown) { sigjmp_buf updbuf; /* recovery buffer for update code */ sigjmp_buf *old_recover; /* previous recovery buffer */ /* This part of the application reads input from stdin ... */ . . . /* This part of the program updates a database and is */ /* protected from SIGINT and SIGALRM interrupts. */ sigprocmask(SIG_BLOCK, &newmask, &oldmask); /* Block signals. */ old_recover = recover; /* Save previous recovery information. */ if (sigsetjmp(updbuf, 1)) { /* error during update */ fputs("SIGSEGV during database update - fixing files\n", stderr); fixfiles(); recover = old_recover; sigprocmask(SIG_SETMASK, &oldmask, 0); /* Restore mask. */ continue; } recover = &updbuf; /* Define new recovery point. */ . . /* Update the database. */ . recover = old_recover; /* Restore old recovery point. */ /* Restore the mask. */ sigprocmask(SIG_SETMASK, &oldmask, NULL); } } static void segv_handler(int signum) { /* This routine handles SIGSEGV errors by escaping to the */ /* cleanup routine identified by recover. The handler has */ /* SIGALRM, SIGINT and SIGTERM signals blocked. The mask */ /* to be used during recovery is unknown. */ btrace(0); /* Get traceback for diagnosis of problem. */ siglongjmp(*recover, 1); /* Escape to cleanup routine. */ }
RELATED FUNCTIONS |
SEE ALSO |
Chapter Contents |
Previous |
Next |
Top of Page |
Copyright © 2001 by SAS Institute Inc., Cary, NC, USA. All rights reserved.