Blame man3/setjmp.3

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/.