|SETJMP(3)||Linux Programmer's Manual||SETJMP(3)|
int setjmp(jmp_buf env); int sigsetjmp(sigjmp_buf env, int savesigs);
noreturn void longjmp(jmp_buf env, int val); noreturn void siglongjmp(sigjmp_buf env, int val);
setjmp(): see NOTES.
The setjmp() function saves various information about the calling environment (typically, the stack pointer, the instruction pointer, possibly the values of other registers and the signal mask) in the buffer env for later use by longjmp(). In this case, setjmp() returns 0.
The longjmp() function uses the information saved in env to transfer control back to the point where setjmp() was called and to restore ("rewind") the stack to its state at the time of the setjmp() call. In addition, and depending on the implementation (see NOTES), the values of some other registers and the process signal mask may be restored to their state at the time of the setjmp() call.
Following a successful longjmp(), execution continues as if setjmp() had returned for a second time. This "fake" return can be distinguished from a true setjmp() call because the "fake" return returns the value provided in val. If the programmer mistakenly passes the value 0 in val, the "fake" return will instead return 1.
If, and only if, the savesigs argument provided to sigsetjmp() is nonzero, the process's current signal mask is saved in env and will be restored if a siglongjmp() is later performed with this env.
The longjmp() or siglongjmp() functions do not return.
|setjmp (), sigsetjmp ()||Thread safety||MT-Safe|
|longjmp (), siglongjmp ()||Thread safety||MT-Safe|
sigsetjmp(), siglongjmp(): POSIX.1-2001, POSIX.1-2008.
setjmp() and longjmp() can be useful for dealing with errors inside deeply nested function calls or to allow a signal handler to pass control to a specific point in the program, rather than returning to the point where the handler interrupted the main program. In the latter case, if you want to portably save and restore signal masks, use sigsetjmp() and siglongjmp(). See also the discussion of program readability below.
The compiler may optimize variables into registers, and longjmp() may restore the values of other registers in addition to the stack pointer and program counter. Consequently, the values of automatic variables are unspecified after a call to longjmp() if they meet all the following criteria:
- they are local to the function that made the corresponding setjmp() call;
- their values are changed between the calls to setjmp() and longjmp(); and
- they are not declared as volatile.
Analogous remarks apply for siglongjmp().
Adding further difficulty, the setjmp() and longjmp() calls may not even be in the same source code module.
In summary, nonlocal gotos can make programs harder to understand and maintain, and an alternative should be used if possible.
If, in a multithreaded program, a longjmp() call employs an env buffer that was initialized by a call to setjmp() in a different thread, the behavior is undefined.
POSIX.1-2008 Technical Corrigendum 2 adds longjmp() and siglongjmp() to the list of async-signal-safe functions. However, the standard recommends avoiding the use of these functions from signal handlers and goes on to point out that if these functions are called from a signal handler that interrupted a call to a non-async-signal-safe function (or some equivalent, such as the steps equivalent to exit(3) that occur upon a return from the initial call to main()), the behavior is undefined if the program subsequently makes a call to a non-async-signal-safe function. The only way of avoiding undefined behavior is to ensure one of the following:
- After long jumping from the signal handler, the program does not call any non-async-signal-safe functions and does not return from the initial call to main().
- Any signal whose handler performs a long jump must be blocked during every call to a non-async-signal-safe function and no non-async-signal-safe functions are called after returning from the initial call to main().