setjmp, sigsetjmp, longjmp, siglongjmp — performing a nonlocal goto
#include <setjmp.h>
int
setjmp( |
jmp_buf env) ; |
int
sigsetjmp( |
sigjmp_buf env, |
int savesigs) ; |
void
longjmp( |
jmp_buf env, |
int val) ; |
void
siglongjmp( |
sigjmp_buf env, |
int val) ; |
Note | |||||
---|---|---|---|---|---|
|
The functions described on this page are used for
performing "nonlocal gotos": transferring execution from one
function to a predetermined location in another function. The
setjmp
() function dynamically
establishes the target to which control will later be
transferred, and longjmp
()
performs the transfer of execution.
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.
sigsetjmp
() and
siglongjmp
() also perform
nonlocal gotos, but provide predictable handling of the
process signal mask.
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
.
setjmp
() and sigsetjmp
() return 0 when called directly;
on the "fake" return that occurs after longjmp
() or siglongjmp
(), the nonzero value specified
in val
is
returned.
The longjmp
() or
siglongjmp
() functions do not
return.
For an explanation of the terms used in this section, see attributes(7).
Interface | Attribute | Value |
setjmp (), sigsetjmp () |
Thread safety | MT-Safe |
longjmp (), siglongjmp () |
Thread safety | MT-Safe |
setjmp
(), longjmp
(): POSIX.1-2001, POSIX.1-2008, C89,
C99.
sigsetjmp
(), siglongjmp
(): POSIX.1-2001,
POSIX.1-2008.
POSIX does not specify whether setjmp
() will save the signal mask (to be
later restored during longjmp
(). In System V it will not. In
4.3BSD it will, and there is a function _setjmp
that will not. On Linux with glibc
versions before 2.19, setjmp
()
follows the System V behavior by default, but the BSD
behavior is provided if the _BSD_SOURCE
feature test macro is defined
and none of _POSIX_SOURCE
,
_POSIX_C_SOURCE
, _XOPEN_SOURCE
, _GNU_SOURCE
, or _SVID_SOURCE
is defined. Since glibc 2.19,
<
setjmp.h
>
exposes only the System V version of setjmp
(). Programs that need the BSD
semantics should replace calls to setjmp
() with calls to sigsetjmp
() with a nonzero savesigs
argument.
setjmp
() and longjmp(3) 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:
Analogous remarks apply for siglongjmp
().
While it can be abused, the traditional C "goto"
statement at least has the benefit that lexical cues (the
goto statement and the target label) allow the programmer
to easily perceive the flow of control. Nonlocal gotos
provide no such cues: multiple setjmp
() calls might employ the same
jmp_buf
variable so that the
content of the variable may change over the lifetime of the
application. Consequently, the programmer may be forced to
perform detailed reading of the code to determine the
dynamic target of a particular longjmp
() call. (To make the programmer's
life easier, each setjmp
()
call should employ a unique jmp_buf
variable.)
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 the function which called setjmp
() returns before longjmp
() is called, the behavior is
undefined. Some kind of subtle or unsubtle chaos is sure to
result.
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
().
This page is part of release 4.07 of the Linux man-pages
project. A
description of the project, information about reporting bugs,
and the latest version of this page, can be found at
https://www.kernel.org/doc/man−pages/.
Copyright (C) 2016 Michael Kerrisk <mtk.manpagesgmail.com> %%%LICENSE_START(GPLv2+_DOC_FULL) This is free documentation; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. The GNU General Public License's references to "object code" and "executables" are to be interpreted as the output of any document formatting or typesetting system, including intermediate and printed output. This manual is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this manual; if not, see <http://www.gnu.org/licenses/>. %%%LICENSE_END Added sigsetjmp, Sun Mar 2 22:03:05 EST 1997, jrvvanzandt.mv.com Modifications, Sun Feb 26 14:39:45 1995, faithcs.unc.edu " |