|
Packit |
7cfc04 |
.\" Copyright (C) 2016 Michael Kerrisk <mtk.manpages@gmail.com>
|
|
Packit |
7cfc04 |
.\"
|
|
Packit |
7cfc04 |
.\" %%%LICENSE_START(GPLv2+_DOC_FULL)
|
|
Packit |
7cfc04 |
.\" This is free documentation; you can redistribute it and/or
|
|
Packit |
7cfc04 |
.\" modify it under the terms of the GNU General Public License as
|
|
Packit |
7cfc04 |
.\" published by the Free Software Foundation; either version 2 of
|
|
Packit |
7cfc04 |
.\" the License, or (at your option) any later version.
|
|
Packit |
7cfc04 |
.\"
|
|
Packit |
7cfc04 |
.\" The GNU General Public License's references to "object code"
|
|
Packit |
7cfc04 |
.\" and "executables" are to be interpreted as the output of any
|
|
Packit |
7cfc04 |
.\" document formatting or typesetting system, including
|
|
Packit |
7cfc04 |
.\" intermediate and printed output.
|
|
Packit |
7cfc04 |
.\"
|
|
Packit |
7cfc04 |
.\" This manual is distributed in the hope that it will be useful,
|
|
Packit |
7cfc04 |
.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
7cfc04 |
.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
Packit |
7cfc04 |
.\" GNU General Public License for more details.
|
|
Packit |
7cfc04 |
.\"
|
|
Packit |
7cfc04 |
.\" You should have received a copy of the GNU General Public
|
|
Packit |
7cfc04 |
.\" License along with this manual; if not, see
|
|
Packit |
7cfc04 |
.\" <http://www.gnu.org/licenses/>.
|
|
Packit |
7cfc04 |
.\" %%%LICENSE_END
|
|
Packit |
7cfc04 |
.\"
|
|
Packit |
7cfc04 |
.TH SETJMP 3 2017-03-13 "" "Linux Programmer's Manual"
|
|
Packit |
7cfc04 |
.SH NAME
|
|
Packit |
7cfc04 |
setjmp, sigsetjmp, longjmp, siglongjmp \- performing a nonlocal goto
|
|
Packit |
7cfc04 |
.SH SYNOPSIS
|
|
Packit |
7cfc04 |
.nf
|
|
Packit |
7cfc04 |
.B #include <setjmp.h>
|
|
Packit |
7cfc04 |
.PP
|
|
Packit |
7cfc04 |
.BI "int setjmp(jmp_buf " env );
|
|
Packit |
7cfc04 |
.BI "int sigsetjmp(sigjmp_buf " env ", int " savesigs );
|
|
Packit |
7cfc04 |
.PP
|
|
Packit |
7cfc04 |
.BI "void longjmp(jmp_buf " env ", int " val );
|
|
Packit |
7cfc04 |
.BI "void siglongjmp(sigjmp_buf " env ", int " val );
|
|
Packit |
7cfc04 |
.fi
|
|
Packit |
7cfc04 |
.PP
|
|
Packit |
7cfc04 |
.in -4n
|
|
Packit |
7cfc04 |
Feature Test Macro Requirements for glibc (see
|
|
Packit |
7cfc04 |
.BR feature_test_macros (7)):
|
|
Packit |
7cfc04 |
.in
|
|
Packit |
7cfc04 |
.PP
|
|
Packit |
7cfc04 |
.BR setjmp ():
|
|
Packit |
7cfc04 |
see NOTES.
|
|
Packit |
7cfc04 |
.PP
|
|
Packit |
7cfc04 |
.BR sigsetjmp ():
|
|
Packit |
7cfc04 |
_POSIX_C_SOURCE
|
|
Packit |
7cfc04 |
.SH DESCRIPTION
|
|
Packit |
7cfc04 |
The functions described on this page are used for performing "nonlocal gotos":
|
|
Packit |
7cfc04 |
transferring execution from one function to a predetermined location
|
|
Packit |
7cfc04 |
in another function.
|
|
Packit |
7cfc04 |
The
|
|
Packit |
7cfc04 |
.BR setjmp ()
|
|
Packit |
7cfc04 |
function dynamically establishes the target to which control
|
|
Packit |
7cfc04 |
will later be transferred, and
|
|
Packit |
7cfc04 |
.BR longjmp ()
|
|
Packit |
7cfc04 |
performs the transfer of execution.
|
|
Packit |
7cfc04 |
.PP
|
|
Packit |
7cfc04 |
The
|
|
Packit |
7cfc04 |
.BR setjmp ()
|
|
Packit |
7cfc04 |
function saves various information about the calling environment
|
|
Packit |
7cfc04 |
(typically, the stack pointer, the instruction pointer,
|
|
Packit |
7cfc04 |
possibly the values of other registers and the signal mask)
|
|
Packit |
7cfc04 |
in the buffer
|
|
Packit |
7cfc04 |
.IR env
|
|
Packit |
7cfc04 |
for later use by
|
|
Packit |
7cfc04 |
.BR longjmp ().
|
|
Packit |
7cfc04 |
In this case,
|
|
Packit |
7cfc04 |
.BR setjmp ()
|
|
Packit |
7cfc04 |
returns 0.
|
|
Packit |
7cfc04 |
.PP
|
|
Packit |
7cfc04 |
The
|
|
Packit |
7cfc04 |
.BR longjmp ()
|
|
Packit |
7cfc04 |
function uses the information saved in
|
|
Packit |
7cfc04 |
.IR env
|
|
Packit |
7cfc04 |
to transfer control back to the point where
|
|
Packit |
7cfc04 |
.BR setjmp ()
|
|
Packit |
7cfc04 |
was called and to restore ("rewind") the stack to its state at the time of the
|
|
Packit |
7cfc04 |
.BR setjmp ()
|
|
Packit |
7cfc04 |
call.
|
|
Packit |
7cfc04 |
In addition, and depending on the implementation (see NOTES),
|
|
Packit |
7cfc04 |
the values of some other registers and the process signal mask
|
|
Packit |
7cfc04 |
may be restored to their state at the time of the
|
|
Packit |
7cfc04 |
.BR setjmp ()
|
|
Packit |
7cfc04 |
call.
|
|
Packit |
7cfc04 |
.PP
|
|
Packit |
7cfc04 |
Following a successful
|
|
Packit |
7cfc04 |
.BR longjmp (),
|
|
Packit |
7cfc04 |
execution continues as if
|
|
Packit |
7cfc04 |
.BR setjmp ()
|
|
Packit |
7cfc04 |
had returned for a second time.
|
|
Packit |
7cfc04 |
This "fake" return can be distinguished from a true
|
|
Packit |
7cfc04 |
.BR setjmp ()
|
|
Packit |
7cfc04 |
call because the "fake" return returns the value provided in
|
|
Packit |
7cfc04 |
.IR val .
|
|
Packit |
7cfc04 |
If the programmer mistakenly passes the value 0 in
|
|
Packit |
7cfc04 |
.IR val ,
|
|
Packit |
7cfc04 |
the "fake" return will instead return 1.
|
|
Packit |
7cfc04 |
.PP
|
|
Packit |
7cfc04 |
.SS sigsetjmp() and siglongjmp()
|
|
Packit |
7cfc04 |
.BR sigsetjmp ()
|
|
Packit |
7cfc04 |
and
|
|
Packit |
7cfc04 |
.BR siglongjmp ()
|
|
Packit |
7cfc04 |
also perform nonlocal gotos, but provide predictable handling of
|
|
Packit |
7cfc04 |
the process signal mask.
|
|
Packit |
7cfc04 |
.PP
|
|
Packit |
7cfc04 |
If, and only if, the
|
|
Packit |
7cfc04 |
.I savesigs
|
|
Packit |
7cfc04 |
argument provided to
|
|
Packit |
7cfc04 |
.BR sigsetjmp ()
|
|
Packit |
7cfc04 |
is nonzero, the process's current signal mask is saved in
|
|
Packit |
7cfc04 |
.I env
|
|
Packit |
7cfc04 |
and will be restored if a
|
|
Packit |
7cfc04 |
.BR siglongjmp ()
|
|
Packit |
7cfc04 |
is later performed with this
|
|
Packit |
7cfc04 |
.IR env .
|
|
Packit |
7cfc04 |
.SH RETURN VALUE
|
|
Packit |
7cfc04 |
.BR setjmp ()
|
|
Packit |
7cfc04 |
and
|
|
Packit |
7cfc04 |
.BR sigsetjmp ()
|
|
Packit |
7cfc04 |
return 0 when called directly;
|
|
Packit |
7cfc04 |
on the "fake" return that occurs after
|
|
Packit |
7cfc04 |
.BR longjmp ()
|
|
Packit |
7cfc04 |
or
|
|
Packit |
7cfc04 |
.BR siglongjmp (),
|
|
Packit |
7cfc04 |
the nonzero value specified in
|
|
Packit |
7cfc04 |
.I val
|
|
Packit |
7cfc04 |
is returned.
|
|
Packit |
7cfc04 |
.PP
|
|
Packit |
7cfc04 |
The
|
|
Packit |
7cfc04 |
.BR longjmp ()
|
|
Packit |
7cfc04 |
or
|
|
Packit |
7cfc04 |
.BR siglongjmp ()
|
|
Packit |
7cfc04 |
functions do not return.
|
|
Packit |
7cfc04 |
.SH ATTRIBUTES
|
|
Packit |
7cfc04 |
For an explanation of the terms used in this section, see
|
|
Packit |
7cfc04 |
.BR attributes (7).
|
|
Packit |
7cfc04 |
.TS
|
|
Packit |
7cfc04 |
allbox;
|
|
Packit |
7cfc04 |
lbw23 lb lb
|
|
Packit |
7cfc04 |
l l l.
|
|
Packit |
7cfc04 |
Interface Attribute Value
|
|
Packit |
7cfc04 |
T{
|
|
Packit |
7cfc04 |
.BR setjmp (),
|
|
Packit |
7cfc04 |
.BR sigsetjmp ()
|
|
Packit |
7cfc04 |
T} Thread safety MT-Safe
|
|
Packit |
7cfc04 |
T{
|
|
Packit |
7cfc04 |
.BR longjmp (),
|
|
Packit |
7cfc04 |
.BR siglongjmp ()
|
|
Packit |
7cfc04 |
T} Thread safety MT-Safe
|
|
Packit |
7cfc04 |
.TE
|
|
Packit |
7cfc04 |
.PP
|
|
Packit |
7cfc04 |
.SH CONFORMING TO
|
|
Packit |
7cfc04 |
.BR setjmp (),
|
|
Packit |
7cfc04 |
.BR longjmp ():
|
|
Packit |
7cfc04 |
POSIX.1-2001, POSIX.1-2008, C89, C99.
|
|
Packit |
7cfc04 |
.PP
|
|
Packit |
7cfc04 |
.BR sigsetjmp (),
|
|
Packit |
7cfc04 |
.BR siglongjmp ():
|
|
Packit |
7cfc04 |
POSIX.1-2001, POSIX.1-2008.
|
|
Packit |
7cfc04 |
.SH NOTES
|
|
Packit |
7cfc04 |
POSIX does not specify whether
|
|
Packit |
7cfc04 |
.BR setjmp ()
|
|
Packit |
7cfc04 |
will save the signal mask
|
|
Packit |
7cfc04 |
(to be later restored during
|
|
Packit |
7cfc04 |
.BR longjmp ()).
|
|
Packit |
7cfc04 |
In System V it will not.
|
|
Packit |
7cfc04 |
In 4.3BSD it will, and there
|
|
Packit |
7cfc04 |
is a function
|
|
Packit |
7cfc04 |
.BR _setjmp ()
|
|
Packit |
7cfc04 |
that will not.
|
|
Packit |
7cfc04 |
The behavior under Linux depends on the glibc version
|
|
Packit |
7cfc04 |
and the setting of feature test macros.
|
|
Packit |
7cfc04 |
On Linux with glibc versions before 2.19,
|
|
Packit |
7cfc04 |
.BR setjmp ()
|
|
Packit |
7cfc04 |
follows the System V behavior by default,
|
|
Packit |
7cfc04 |
but the BSD behavior is provided if the
|
|
Packit |
7cfc04 |
.BR _BSD_SOURCE
|
|
Packit |
7cfc04 |
feature test macro is explicitly defined
|
|
Packit |
7cfc04 |
.\" so that _FAVOR_BSD is triggered
|
|
Packit |
7cfc04 |
and none of
|
|
Packit |
7cfc04 |
.BR _POSIX_SOURCE ,
|
|
Packit |
7cfc04 |
.BR _POSIX_C_SOURCE ,
|
|
Packit |
7cfc04 |
.BR _XOPEN_SOURCE ,
|
|
Packit |
7cfc04 |
.\" .BR _XOPEN_SOURCE_EXTENDED ,
|
|
Packit |
7cfc04 |
.BR _GNU_SOURCE ,
|
|
Packit |
7cfc04 |
or
|
|
Packit |
7cfc04 |
.B _SVID_SOURCE
|
|
Packit |
7cfc04 |
is defined.
|
|
Packit |
7cfc04 |
Since glibc 2.19,
|
|
Packit |
7cfc04 |
.IR <setjmp.h>
|
|
Packit |
7cfc04 |
exposes only the System V version of
|
|
Packit |
7cfc04 |
.BR setjmp ().
|
|
Packit |
7cfc04 |
Programs that need the BSD semantics should replace calls to
|
|
Packit |
7cfc04 |
.BR setjmp ()
|
|
Packit |
7cfc04 |
with calls to
|
|
Packit |
7cfc04 |
.BR sigsetjmp ()
|
|
Packit |
7cfc04 |
with a nonzero
|
|
Packit |
7cfc04 |
.I savesigs
|
|
Packit |
7cfc04 |
argument.
|
|
Packit |
7cfc04 |
.PP
|
|
Packit |
7cfc04 |
.BR setjmp ()
|
|
Packit |
7cfc04 |
and
|
|
Packit |
7cfc04 |
.BR longjmp ()
|
|
Packit |
7cfc04 |
can be useful for dealing with errors inside deeply nested function calls
|
|
Packit |
7cfc04 |
or to allow a signal handler to pass control to
|
|
Packit |
7cfc04 |
a specific point in the program,
|
|
Packit |
7cfc04 |
rather than returning to the point where the handler interrupted
|
|
Packit |
7cfc04 |
the main program.
|
|
Packit |
7cfc04 |
In the latter case,
|
|
Packit |
7cfc04 |
if you want to portably save and restore signal masks, use
|
|
Packit |
7cfc04 |
.BR sigsetjmp ()
|
|
Packit |
7cfc04 |
and
|
|
Packit |
7cfc04 |
.BR siglongjmp ().
|
|
Packit |
7cfc04 |
See also the discussion of program readability below.
|
|
Packit |
7cfc04 |
.PP
|
|
Packit |
7cfc04 |
The compiler may optimize variables into registers, and
|
|
Packit |
7cfc04 |
.BR longjmp ()
|
|
Packit |
7cfc04 |
may restore the values of other registers in addition to the
|
|
Packit |
7cfc04 |
stack pointer and program counter.
|
|
Packit |
7cfc04 |
Consequently, the values of automatic variables are unspecified
|
|
Packit |
7cfc04 |
after a call to
|
|
Packit |
7cfc04 |
.BR longjmp ()
|
|
Packit |
7cfc04 |
if they meet all the following criteria:
|
|
Packit |
7cfc04 |
.IP \(bu 3
|
|
Packit |
7cfc04 |
they are local to the function that made the corresponding
|
|
Packit |
7cfc04 |
.BR setjmp ()
|
|
Packit |
7cfc04 |
call;
|
|
Packit |
7cfc04 |
.IP \(bu
|
|
Packit |
7cfc04 |
their values are changed between the calls to
|
|
Packit |
7cfc04 |
.BR setjmp ()
|
|
Packit |
7cfc04 |
and
|
|
Packit |
7cfc04 |
.BR longjmp ();
|
|
Packit |
7cfc04 |
and
|
|
Packit |
7cfc04 |
.IP \(bu
|
|
Packit |
7cfc04 |
they are not declared as
|
|
Packit |
7cfc04 |
.IR volatile .
|
|
Packit |
7cfc04 |
.PP
|
|
Packit |
7cfc04 |
Analogous remarks apply for
|
|
Packit |
7cfc04 |
.BR siglongjmp ().
|
|
Packit |
7cfc04 |
.\"
|
|
Packit |
7cfc04 |
.SS Nonlocal gotos and program readability
|
|
Packit |
7cfc04 |
While it can be abused,
|
|
Packit |
7cfc04 |
the traditional C "goto" statement at least has the benefit that lexical cues
|
|
Packit |
7cfc04 |
(the goto statement and the target label)
|
|
Packit |
7cfc04 |
allow the programmer to easily perceive the flow of control.
|
|
Packit |
7cfc04 |
Nonlocal gotos provide no such cues: multiple
|
|
Packit |
7cfc04 |
.BR setjmp ()
|
|
Packit |
7cfc04 |
calls might employ the same
|
|
Packit |
7cfc04 |
.IR jmp_buf
|
|
Packit |
7cfc04 |
variable so that the content of the variable may change
|
|
Packit |
7cfc04 |
over the lifetime of the application.
|
|
Packit |
7cfc04 |
Consequently, the programmer may be forced to perform detailed
|
|
Packit |
7cfc04 |
reading of the code to determine the dynamic target of a particular
|
|
Packit |
7cfc04 |
.BR longjmp ()
|
|
Packit |
7cfc04 |
call.
|
|
Packit |
7cfc04 |
(To make the programmer's life easier, each
|
|
Packit |
7cfc04 |
.BR setjmp ()
|
|
Packit |
7cfc04 |
call should employ a unique
|
|
Packit |
7cfc04 |
.IR jmp_buf
|
|
Packit |
7cfc04 |
variable.)
|
|
Packit |
7cfc04 |
.PP
|
|
Packit |
7cfc04 |
Adding further difficulty, the
|
|
Packit |
7cfc04 |
.BR setjmp ()
|
|
Packit |
7cfc04 |
and
|
|
Packit |
7cfc04 |
.BR longjmp ()
|
|
Packit |
7cfc04 |
calls may not even be in the same source code module.
|
|
Packit |
7cfc04 |
.PP
|
|
Packit |
7cfc04 |
In summary, nonlocal gotos can make programs harder to understand
|
|
Packit |
7cfc04 |
and maintain, and an alternative should be used if possible.
|
|
Packit |
7cfc04 |
.\"
|
|
Packit |
7cfc04 |
.SS Caveats
|
|
Packit |
7cfc04 |
If the function which called
|
|
Packit |
7cfc04 |
.BR setjmp ()
|
|
Packit |
7cfc04 |
returns before
|
|
Packit |
7cfc04 |
.BR longjmp ()
|
|
Packit |
7cfc04 |
is called, the behavior is undefined.
|
|
Packit |
7cfc04 |
Some kind of subtle or unsubtle chaos is sure to result.
|
|
Packit |
7cfc04 |
.PP
|
|
Packit |
7cfc04 |
If, in a multithreaded program, a
|
|
Packit |
7cfc04 |
.BR longjmp ()
|
|
Packit |
7cfc04 |
call employs an
|
|
Packit |
7cfc04 |
.I env
|
|
Packit |
7cfc04 |
buffer that was initialized by a call to
|
|
Packit |
7cfc04 |
.BR setjmp ()
|
|
Packit |
7cfc04 |
in a different thread, the behavior is undefined.
|
|
Packit |
7cfc04 |
.\"
|
|
Packit |
7cfc04 |
.\" The following statement appeared in versions up to POSIX.1-2008 TC1,
|
|
Packit |
7cfc04 |
.\" but is set to be removed in POSIX.1-2008 TC2:
|
|
Packit |
7cfc04 |
.\"
|
|
Packit |
7cfc04 |
.\" According to POSIX.1, if a
|
|
Packit |
7cfc04 |
.\" .BR longjmp ()
|
|
Packit |
7cfc04 |
.\" call is performed from a nested signal handler
|
|
Packit |
7cfc04 |
.\" (i.e., from a handler that was invoked in response to a signal that was
|
|
Packit |
7cfc04 |
.\" generated while another signal was already in the process of being
|
|
Packit |
7cfc04 |
.\" handled), the behavior is undefined.
|
|
Packit |
7cfc04 |
.PP
|
|
Packit |
7cfc04 |
POSIX.1-2008 Technical Corrigendum 2 adds
|
|
Packit |
7cfc04 |
.\" http://austingroupbugs.net/view.php?id=516#c1195
|
|
Packit |
7cfc04 |
.BR longjmp ()
|
|
Packit |
7cfc04 |
and
|
|
Packit |
7cfc04 |
.BR siglongjmp ()
|
|
Packit |
7cfc04 |
to the list of async-signal-safe functions.
|
|
Packit |
7cfc04 |
However, the standard recommends avoiding the use of these functions
|
|
Packit |
7cfc04 |
from signal handlers and goes on to point out that
|
|
Packit |
7cfc04 |
if these functions are called from a signal handler that interrupted
|
|
Packit |
7cfc04 |
a call to a non-async-signal-safe function (or some equivalent,
|
|
Packit |
7cfc04 |
such as the steps equivalent to
|
|
Packit |
7cfc04 |
.BR exit (3)
|
|
Packit |
7cfc04 |
that occur upon a return from the initial call to
|
|
Packit |
7cfc04 |
.IR main ()),
|
|
Packit |
7cfc04 |
the behavior is undefined if the program subsequently makes a call to
|
|
Packit |
7cfc04 |
a non-async-signal-safe function.
|
|
Packit |
7cfc04 |
The only way of avoiding undefined behavior is to ensure one of the following:
|
|
Packit |
7cfc04 |
.IP * 3
|
|
Packit |
7cfc04 |
After long jumping from the signal handler,
|
|
Packit |
7cfc04 |
the program does not call any non-async-signal-safe functions
|
|
Packit |
7cfc04 |
and does not return from the initial call to
|
|
Packit |
7cfc04 |
.IR main ().
|
|
Packit |
7cfc04 |
.IP *
|
|
Packit |
7cfc04 |
Any signal whose handler performs a long jump must be blocked during
|
|
Packit |
7cfc04 |
.I every
|
|
Packit |
7cfc04 |
call to a non-async-signal-safe function and
|
|
Packit |
7cfc04 |
no non-async-signal-safe functions are called after
|
|
Packit |
7cfc04 |
returning from the initial call to
|
|
Packit |
7cfc04 |
.IR main ().
|
|
Packit |
7cfc04 |
.SH SEE ALSO
|
|
Packit |
7cfc04 |
.BR signal (7),
|
|
Packit |
7cfc04 |
.BR signal-safety (7)
|
|
Packit |
7cfc04 |
.SH COLOPHON
|
|
Packit |
7cfc04 |
This page is part of release 4.15 of the Linux
|
|
Packit |
7cfc04 |
.I man-pages
|
|
Packit |
7cfc04 |
project.
|
|
Packit |
7cfc04 |
A description of the project,
|
|
Packit |
7cfc04 |
information about reporting bugs,
|
|
Packit |
7cfc04 |
and the latest version of this page,
|
|
Packit |
7cfc04 |
can be found at
|
|
Packit |
7cfc04 |
\%https://www.kernel.org/doc/man\-pages/.
|