sigsetjmp()--Set Jump Point for Nonlocal Goto


  Syntax
 #include <setjmp.h>

 int sigsetjmp( sigjmp_buf env, int savemask );   

  Service Program Name: QPOSSRV1

  Default Public Authority: *USE

  Threadsafe: Yes

The sigsetjmp() function saves the current stack environment and, optionally, the current signal mask. The stack environment and signal mask saved by sigsetjmp() can subsequently be restored by siglongjmp().

sigsetjmp() is similar to setjmp(), except for the optional capability of saving the signal mask. Like setjmp() and longjmp(), the sigsetjmp() and siglongjmp() functions provide a way to perform a nonlocal "goto."

A call to sigsetjmp() causes it to save the current stack environment in env. If the value of the savemask parameter is nonzero, sigsetjmp() also saves the current signal mask in env. A subsequent call to siglongjmp() does the following:

The values of all variables (except register variables) accessible to the function receiving control contain the values they had when siglongjmp() was called. The values of register variables are unpredictable. Nonvolatile automatic storage variables that are changed between calls to sigsetjmp() and siglongjmp() are also unpredictable.


Authorities and Locks

None.


Parameters

env
(Input) An array type for holding the information needed to restore a calling environment.

savemask
(Input) An indicator used to determine if the current signal mask of the thread is to be saved. This value may be zero.

Return Value

0 sigsetjmp() was called to save the stack environment and, optionally, the signal mask. It may have been either successful or not successful.
val siglongjmp() caused control to be transferred to the place in the user's program where sigsetjmp() was issued. The value returned is the value specified on siglongjmp() for the val parameter (or 1 if the value of val is zero).


Error Conditions

The sigsetjmp() function does not return an error.


Usage Notes

The sigsetjmp()-siglongjmp() pair and the setjmp()-longjmp() pair cannot be intermixed. A stack environment and signal mask saved by sigsetjmp() can be restored only by siglongjmp().


Related Information


Example

See Code disclaimer information for information pertaining to code examples.

This example saves the stack environment and signal mask at the following statement:

    if( sigsetjmp(mark,1) != 0 ) { ...

When the system first performs the if statement, it saves the environment and signal mask in mark and sets the condition to false because sigsetjmp() returns a 0 when it saves the environment. The program prints the following message:

    sigsetjmp() has been called

The subsequent call to function p() tests for a local error condition, which can cause it to perform siglongjmp() (in this example as a result of calling a signal catching function). Control is returned to the original sigsetjmp() function using the environment saved in mark and the restored signal mask. This time, the condition is true because -1 is the return value from siglongjmp(). The program then performs the statements in the block and prints the following:

    siglongjmp() function was called

Then the program performs the recover() function and exits.

Here is the program:

#include <signal.h>
#include <setjmp.h>
#include <unistd.h>
#include <stdio.h>

sigset_t sigset;
sigjmp_buf mark;

void catcher( int );
void p( void );
void recover( void );

int main( int argc, char *argv[] ) {

    int result;

    /*
     * Block the SIGUSR1 and SIGUSR2 signals.  This set of
     * signals will be saved as part of the environment
     * by the sigsetjmp() function.
     */

     sigemptyset( &sigset );
     sigaddset( &sigset, SIGUSR1 );
     sigaddset( &sigset, SIGUSR2 );
     sigprocmask( SIG_SETMASK, &sigset, NULL );

     if( sigsetjmp( mark, 1 ) != 0 ) {
         printf( "siglongjmp() function was called\n" );
         recover();
         result=0;
     }
     else {
         printf( "sigsetjmp() has been called\n" );
         p();
         sigprocmask( SIG_SETMASK, NULL, &sigset );
         if( sigismember( &sigset, SIGUSR2 ) )
             printf( "siglongjmp() was not called\n" );
         result=-1;
    }
    printf( "return to main with result %d\n", result);

    return( result );
}

void p( void ) {

    struct sigaction sigact;
    int error=0;

    printf( "performing function p()\n" );

    /* Send signal handler in case error condition is detected */

    sigemptyset( &sigact.sa_mask );
    sigact.sa_flags = 0;
    sigact.sa_handler = catcher;
    sigaction( SIGUSR2, &sigact, NULL );

    sigdelset( &sigset, SIGUSR2 );
    sigprocmask( SIG_SETMASK, &sigset, NULL );

    /* After some processing an error condition is detected */

    error=-1;

    /* Call catcher() function if error is detected */

    if( error != 0 ) {
        printf( "error condition detected, send SIGUSR2 signal\n" );
        kill( getpid(), SIGUSR2 );
    }
    printf( "return from catcher() function is an error\n" );
}

void recover( void ) {

     printf( "taking recovery action\n" );

     sigprocmask( SIG_SETMASK, NULL, &sigset );
     if( sigismember( &sigset, SIGUSR2 ) )
         printf( "signal mask was restored after siglongjmp()\n" );
}

void catcher( int signo ) {

    printf( "in catcher() before siglongjmp()\n" );

    siglongjmp( mark, -1 );

    printf( "in catcher() after siglongjmp() is an error\n" );
}

Output:

    sigsetjmp() has been called
    performing function p()
    error condition detected, send SIGUSR2 signal
    in catcher() before siglongjmp()
    siglongjmp() function was called
    taking recovery action
    signal mask was restored after siglongjmp()
    return to main with result 0


API introduced: V3R6
Top | UNIX-Type APIs | APIs by category