siglongjmp()--Perform Nonlocal Goto with Signal Handling


  Syntax
 #include <setjmp.h>

 void siglongjmp( sigjmp_buf env, int val );   

  Service Program Name: QPOSSRV1

  Default Public Authority: *USE

  Threadsafe: Yes

The siglongjmp() function restores the stack environment previously saved in env by sigsetjmp(). siglongjmp() also provides the option to restore the signal mask, depending on whether the signal mask was saved by sigsetjmp().

siglongjmp() is similar to longjmp(), except for the optional capability of restoring the signal mask.

The sigsetjmp() and siglongjmp() functions provide a way to perform a nonlocal "goto."

A call to sigsetjmp() causes the current stack environment (including, optionally, the signal mask) to be saved in env. A subsequent call to siglongjmp() does the following:

Processing resumes as if the sigsetjmp() call had just returned the given val. All variables, (except register variables) that are accessible to the function that receives control contain the values they had when siglongjmp() was called. The values of register variables are unpredictable. Nonvolatile auto variables that are changed between calls to sigsetjmp() and siglongjmp() are also unpredictable.

Note: When using siglongjmp(), the function in which the corresponding call to sigsetjmp() was made must not have returned first. Unpredictable program behavior occurs if siglongjmp() is called after the function calling sigsetjmp() has returned.

The val argument passed to siglongjmp() must be nonzero. If the val argument is equal to zero, siglongjmp() substitutes a 1 in its place.

siglongjmp() does not use the normal function call and return mechanisms. siglongjmp() restores the saved signal mask only if the env parameter was initialized by a call to sigsetjmp() with a nonzero savemask argument.


Authorities and Locks

None.


Parameters

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

val
(Input) The return value.

Return Value

None.


Error Conditions

The siglongjmp() 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