siglongjmp() — Restore the stack environment and signal mask

Standards

Standards / Extensions C or C++ Dependencies

POSIX.1
XPG4
XPG4.2
Single UNIX Specification, Version 3

both  

Format

#define _POSIX_SOURCE
#include <setjmp.h>

void siglongjmp(sigjmp_buf env, int val);

General description

For a stack environment previously saved in env by sigsetjmp(), the siglongjmp() function restores all the stack environment and, optionally, the signal mask, depending on whether it was saved by sigsetjmp(). The sigsetjmp() and siglongjmp() functions provide a way to perform a nonlocal goto.

env is an address for a sigjmp_buf structure.

val is the return value from siglongjmp().

siglongjmp() is similar to longjmp(), except for the optional capability of restoring the signal mask. The sigsetjmp()—siglongjmp() pair, the setjmp()—longjmp() pair, the _setjmp()—_longjmp() pair, and the getcontext()—setcontext() pair cannot be intermixed. A stack environment and signal mask saved by sigsetjmp() can be restored only by siglongjmp().

A call to sigsetjmp() causes the current stack environment including, optionally, the signal mask to be saved in env. A subsequent call to siglongjmp() restores the saved environment and signal mask (if saved by sigsetjmp()) and returns control to a point in the program corresponding to the sigsetjmp() call. Execution resumes as if the sigsetjmp() call had just returned the given value. All variables (except register variables) that are accessible to the function that receives control contain the values they had when you called siglongjmp(). The values of register variables are unpredictable. Nonvolatile auto variables that are changed between calls to sigsetjmp() and siglongjmp() are also unpredictable.
Notes:
  1. If you call siglongjmp(), the function in which the corresponding call to sigsetjmp() was made must not have returned first. After the function calling sigsetjmp() returns, calling siglongjmp() causes unpredictable program behavior.
  2. If siglongjmp() is used to jump back into an XPLINK routine, any alloca() requests issued by the XPLINK routine after the earlier sigsetjmp() (or getcontext(),and so on.) was called and before siglongjmp() is called are backed out. All storage obtained by these alloca() requests is freed before the XPLINK routine is resumed.
  3. If siglongjmp() is used to jump back into a non-XPLINK routine, alloca() requests made after sigsetjmp() and before siglongjmp() are not backed out.

The value argument passed to siglongjmp() must be nonzero. If you give a zero argument for value, siglongjmp() substitutes the value 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.

Special behavior for C++: If sigsetjmp() and siglongjmp() are used to transfer control in a z/OS® XL C++ program, the behavior is undefined in terms of the destruction of automatic objects. 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 siglongjmp() 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 sigsetjmp() and siglongjmp() in conjunction with try(), catch(), and throw() is also undefined.

Special behavior for XPLINK-compiled C++: Restrictions concerning setjmp.h and ucontext.h:
  1. All XPLINK programs compiled with the V2R10 or later C compilers that are to run with Language Environment V2R10 or later libraries and use the jmp_buf, sigjmp_buf or ucontext_t types must not be compiled with C headers from Language Environment V2R9 or earlier.
  2. Non-XPLINK functions compiled with any level of Language Environment headers must not define jmp_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 Language Environment V2R10 and later headers define a larger jmp_buf, sigjmp_buf or ucontext_t area that is required by setjmp(), getcontext(), and related functions when they are called from an XPLINK routine. If __XPLINK__ is not defined, the Language Environment V2R10 and later headers define a shorter jmp_buf, sigjmp_buf or ucontext_t area. The Language Environment headers before V2R10 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

siglongjmp() returns no values.

There are no documented errno values.

Example

This example saves the stack environment and signal mask at the 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 0 when it saves the environment. The program prints the message: sigsetjmp() has been called

The subsequent call to function p() tests for a local error condition, which can cause it to perform siglongjmp(). Then control returns to the original sigsetjmp() function using the environment saved in mark and restores the signal mask. This time the condition is true because -1 is the return value from siglongjmp(). The example then performs the statements in the block and prints: siglongjmp() has been called Then it performs your recover() function and leaves the program.
#define _POSIX_SOURCE
#include <stdio.h>
#include <setjmp.h>

sigjmp_buf mark;

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

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

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

void recover(void) {
⋮
}

Related information