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

Note: By using the code examples, you agree to the terms of the Code license and disclaimer information.

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

    returnCode = sigsetjmp( mark, 1 );

When the system first performs the sigsetjmp(), it saves the environment and signal mask in mark and sets returnCode to 0 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, returnCode contains -1 because this is the return value from siglongjmp().

The program then performs the statements for the case -1 leg of the switch statement and prints the following message:

    siglongjmp() function was called

A test is performed to demonstrate that the signal mask was restored and prints the following:

    signal mask was restored after siglongjmp()

Then the program exits. End of change

Here is the program:

Start of change
#include <signal.h>
#include <setjmp.h>
#include <unistd.h>
#include <stdio.h>

sigset_t sigset;
sigjmp_buf mark;
int catcherWasCalled;

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

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

    int result = 0;
    int returnCode = 0;

    /*
     * Block the SIGUSR2 signal.  This signal set will be
     * saved as part of the environment by the sigsetjmp()
     * function and subsequently restored by the siglongjmp()
     * function.
     */

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

     /* Save the stack environment and the current signal mask */
   
     returnCode = sigsetjmp( mark, 1 );

     /* Handle the sigsetjmp return code */

     switch ( returnCode ) {

	 case  0 : {
             printf( "sigsetjmp() has been called\n" );

            /*
             * Call function p() which will call the siglongjmp() 
             * function
             */

             p();

             printf( "control returning here is an error\n" );
             result=-1;
             break;
	 }

	 case -1 : {
             printf( "siglongjmp() function was called\n" );

             /* Retrieve the current signal mask */
           
             sigprocmask( SIG_SETMASK, NULL, &sigset );

             /* Verify SIGUSR2 is in sigset */
	     if( sigismember( &sigset, SIGUSR2 ) ) {
               printf( "signal mask was restored after siglongjmp()\n" );
               result=0;
	     }
	     else {
               printf( "signal mask was not restored after siglongjmp()\n" );
               result=-1;
	     }
             break;
	 }

	 default: {
             printf( "this unexpected return code is an error\n" );
             result=-1;
             break;
	 }
     }

    printf( "return from main with result %d\n", result );

    return( result );
}

void p( void ) {

    struct sigaction sigact;
    int error=0;

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

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

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

   /*
    * Delete SIGUSR2 from the signal set that was initialized
    * by the main() function. This allows us to demonstrate
    * that the original signal set saved by the sigsetjmp() function
    * is restored by the siglongjmp() function.
    */

    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 ) {
        catcherWasCalled = 0;

        /* Send SIGUSR2 to handle the error condition */

        printf( "error condition detected, send SIGUSR2 signal\n" );
        kill( getpid(), SIGUSR2 );

	if( catcherWasCalled == 1 ) {

            printf( "catcher() function handled the error condition\n" );

           /*
            * Perform a nonlocal "goto" and specify -1 for the
            * return value
            */

            siglongjmp( mark, -1 );

            printf( "control getting here is an error\n" );
	}
    }
}

void catcher( int signo ) {

   /*
    * Indicate the catcher() function is handling the
    * SIGUSR2 signal.
    */

    catcherWasCalled = 1;
}

Output

    sigsetjmp() has been called
    performing function p()
    error condition detected, send SIGUSR2 signal
    catcher() function handled the error condition
    siglongjmp() function was called
    signal mask was restored after siglongjmp()
    return from main with result 0

End of change

API introduced: V3R6

[ Back to top | UNIX-Type APIs | APIs by category ]