### setjmp -- Preserve Environment

Format

>     #include <setjmp.h>
>     int setjmp(jmp_buf env);

Language Level: ANSI, POSIX, XPG4
setjmp saves a stack environment that can subsequently be restored by longjmp. setjmp and longjmp provide a way to perform a nonlocal goto. They are often used in signal handlers.

A call to setjmp causes it to save the current stack environment in env. A subsequent call to longjmp restores the saved environment and returns control to a point corresponding to the setjmp call. The values of all variables (except register variables) accessible to the function receiving control contain the values they had when longjmp was called. The values of variables that are allocated to registers by the compiler are unpredictable. Because any auto variable could be allocated to a register in optimized code, you should consider the values of all auto variables to be unpredictable after a longjmp call.

C++ Considerations: When you call setjmp in a C++ program, ensure that the same part of the program does not also create C++ objects that need to be destroyed. When you call longjmp, objects existing at the time of the setjmp call will still exist, but any destructors called after setjmp are not called.

Return Value
setjmp returns the value 0 after saving the stack environment. If setjmp returns as a result of a longjmp call, it returns the value argument of longjmp, or 1 if the value argument of longjmp is 0. There is no error return value.

Example
This example stores the stack environment at the statement

> `if(setjmp(mark) != 0)` ...

When the system first performs the if statement, it saves the environment in mark and sets the condition to FALSE because setjmp returns a 0 when it saves the environment. The program prints the message

> `setjmp has been called`

The subsequent call to function p tests for a local error condition, which can cause it to perform the longjmp function. Then, control returns to the original function using the environment saved in mark. This time, the condition is TRUE because -1 is the return value from the longjmp function. The program then performs the statements in the block and prints

> `longjmp has been called`

Then the program calls the recover function and exits.

    #include <stdio.h>
    #include <stdlib.h>
    #include <setjmp.h>

    jmp_buf mark;

    void p(void)
    {
       int error = 0;   /* assume no errors will occur */

       /*
         .
         .
         .
       */

            error = 9;   /* Serious error occurred */
       /*
         .
         .
         .
       */

       if (error != 0)
          longjmp(mark, -1);

       /*
         .
         .
         .
       */
    }

    void recover(void)
    {
       /* Take action to recover from the error */
       printf("recover has been called\n");
       return;
    }

    int main(void)
    {
       if (setjmp(mark) != 0) {
          printf("longjmp has been called\n");
          recover();
          return 0;
       }
       printf("setjmp has been called\n");

       p();

       return 0;

       /*******************************************
          The output should be:

          setjmp has been called
          longjmp has been called
          recover has been called
       *******************************************/
    }

longjmp -- Restore Stack Environment
<setjmp.h>