longjmp() — Restore stack environment

Standards

Standards / Extensions C or C++ Dependencies

ISO C
POSIX.1
XPG4
XPG4.2
C99
C11
Single UNIX Specification, Version 3

both  

Format

#include <setjmp.h>

__noreturn__ void longjmp(jmp_buf env, int value);

General description

Restores a stack environment previously saved in env by setjmp(). The setjmp() and longjmp() functions provide a way to perform a nonlocal goto. They are often used in signal handlers.

A call to setjmp() causes the current stack environment to be saved in env. A subsequent call to longjmp() restores the saved environment, and returns control to a point in the program corresponding to the setjmp() call. Execution resumes as if the setjmp() call had just returned the given value of the value argument. All variables that are accessible to the function that receives control contain the values they had when longjmp() was called. The values of register variables are unpredictable. Nonvolatile auto variables that are changed between calls to setjmp() and longjmp() are also unpredictable.
Note: Ensure that the function that calls setjmp() does not return before you call the corresponding longjmp() function. Calling longjmp() after the function calling setjmp() returns causes unpredictable program behavior.
The value argument passed to longjmp() must be nonzero. If you give a 0 argument for value, longjmp() substitutes a 1 in its place.
Notes:
  1. If longjmp() is used to jump back into an XPLink routine, any alloca() requests issued by the XPLink routine after the earlier setjmp() (or _setjmp(), sigsetjmp(), getcontext(), and so on) was called and before longjmp() is called are backed out. All storage obtained by these alloca() requests is freed before the XPLink routine is resumed.
  2. If longjmp() is used to jump back into a non-XPLink routine, alloca() requests made after setjmp() (and so on) and before longjmp() are not backed out.

Special behavior for POSIX: In a POSIX program, the signal mask is not saved. Thus, to save and restore a stack environment that includes the current signal mask, use sigsetjmp() and siglongjmp() instead of setjmp() and longjmp(). The sigsetjmp()—siglongjmp() pair, the setjmp()—longjmp() pair, the _setjmp()—_longjmp() pair, and the getcontext()—setcontext() pair cannot be intermixed. A stack environment saved by setjmp() can be restored only by longjmp().

Special behavior for C++: If setjmp() and longjmp() are used to transfer control in a z/OS® XL C++ program, the behavior in terms of the destruction of automatic objects is undefined. Additionally, if any automatic objects would be destroyed by a thrown exception transferring control to another (destination) point in the program, then a call to longjmp() at the throw point that transfers control to the same (destination) point has undefined behavior. This applies to both z/OS XL C++ and z/OS XL C/C++ ILC modules. The use of setjmp() and longjmp() in conjunction with try(), catch(), and throw() is also undefined.

Special behavior for XPG4.2: In a program that was compiled with the feature test macro, _XOPEN_SOURCE_EXTENDED, defined, another pair of functions, _setjmp()—_longjmp() are available. These functions are, on this implementation, functionally identical to setjmp()—longjmp(). Therefore it is possible, but not recommended, to intermix the setjmp()—longjmp() pair with the _setjmp()—_longjmp() pair.

Special behavior for XPLINK-compiled C++: Restrictions concerning setjmp.h and ucontext.h:
  1. All XPLINK programs compiled with the Release 10 or later C compilers that are to run with Language Environment Release 10 or later libraries and use the jmp_buf, sigjmp_buf or ucontext_t types must not be compiled with C headers from Language Environment® 2.9 or earlier.
  2. Non-XPLINK functions compiled with any level of Language Environment headers must not definejmp_buf, sigjmp_buf or ucontext_t data items and pass them to XPLINK functions that call getcontext(), longjmp(), _longjmp(), setjmp(), _setjmp(), setcontext(), sigsetjmp(), or swapcontext() with these passed-in data items.
  3. When __XPLINK__ is defined, the Release 10 and later headers define a larger jmp_buf, sigjmp_buf or ucontext_tarea that is required by setjmp(), getcontext(), and related functions when they are called from an XPLINK routine. If __XPLINK__ is not defined, the Release 10 and later headers define a shorter jmp_buf, sigjmp_buf or ucontext_t area. The Language Environment headers before Release 10 also define the shorter version of these data areas. If an XPLINK function calls setjmp(), getcontext() or similar functions with a short jmp_buf, sigjmp_buf or ucontext_t area, a storage overlay or program check may occur when the C library tries to store past the end of the passed-in (too short) data area.

Returned value

longjmp() does not use the normal function call and return mechanisms; it returns no values.

Example

This example provides for saving the stack environment at this 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 setjmp() function using the environment saved in mark. This time the condition is TRUE because -1 is the returned value from the longjmp() function. The example then performs the statements in the block and prints: longjmp has been called

It then performs the recover function and leaves the program.
/*    Illustration of longjmp().     */
#include <stdio.h>
#include <setjmp.h>

jmp_buf mark;

void p(void);
void recover(void);

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

void p(void)
{
   int error = 0;
⋮
   error = 9;
⋮
   if (error != 0)
      longjmp(mark, -1);
⋮
}

void recover(void)
{
⋮
}

Related information