mirror of https://github.com/mkerrisk/man-pages
setjmp.3: Rewrite and merge longjmp()/siglongjmp() discussion into this page
The discussion of nonlocal gotos is much easier to read if setjmp() and longjmp() are discussed in the same page. While we're at it, rework almost the entire text and add several more details. Signed-off-by: Michael Kerrisk <mtk.manpages@gmail.com>
This commit is contained in:
parent
84d75c06d5
commit
efc626f8f5
212
man3/setjmp.3
212
man3/setjmp.3
|
@ -1,4 +1,4 @@
|
||||||
.\" Written by Michael Haardt, Fri Nov 25 14:51:42 MET 1994
|
.\" Copyright (C) 2016 Michael Kerrisk <mtk.manpages@gmail.com>
|
||||||
.\"
|
.\"
|
||||||
.\" %%%LICENSE_START(GPLv2+_DOC_FULL)
|
.\" %%%LICENSE_START(GPLv2+_DOC_FULL)
|
||||||
.\" This is free documentation; you can redistribute it and/or
|
.\" This is free documentation; you can redistribute it and/or
|
||||||
|
@ -26,14 +26,16 @@
|
||||||
.\" "
|
.\" "
|
||||||
.TH SETJMP 3 2015-08-08 "" "Linux Programmer's Manual"
|
.TH SETJMP 3 2015-08-08 "" "Linux Programmer's Manual"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
setjmp, sigsetjmp \- save stack context for nonlocal goto
|
setjmp, sigsetjmp, longjmp, siglongjmp \- performing a nonlocal goto
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.B #include <setjmp.h>
|
.B #include <setjmp.h>
|
||||||
.sp
|
.sp
|
||||||
.nf
|
.nf
|
||||||
.BI "int setjmp(jmp_buf " env );
|
.BI "int setjmp(jmp_buf " env );
|
||||||
|
|
||||||
.BI "int sigsetjmp(sigjmp_buf " env ", int " savesigs );
|
.BI "int sigsetjmp(sigjmp_buf " env ", int " savesigs );
|
||||||
|
|
||||||
|
.BI "void longjmp(jmp_buf " env ", int " val );
|
||||||
|
.BI "void siglongjmp(sigjmp_buf " env ", int " val );
|
||||||
.fi
|
.fi
|
||||||
.sp
|
.sp
|
||||||
.in -4n
|
.in -4n
|
||||||
|
@ -44,76 +46,128 @@ Feature Test Macro Requirements for glibc (see
|
||||||
.BR setjmp ():
|
.BR setjmp ():
|
||||||
see NOTES.
|
see NOTES.
|
||||||
.br
|
.br
|
||||||
.BR sigsetjmp ():
|
.BR sigsetjmp (),
|
||||||
|
.BR siglongjmp ():
|
||||||
_POSIX_C_SOURCE\ >=\ 1 || _XOPEN_SOURCE || _POSIX_C_SOURCE
|
_POSIX_C_SOURCE\ >=\ 1 || _XOPEN_SOURCE || _POSIX_C_SOURCE
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
|
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
|
||||||
.BR setjmp ()
|
.BR setjmp ()
|
||||||
and
|
function dynamically establishes the target to which control
|
||||||
.BR longjmp (3)
|
will later be transferred, and
|
||||||
are useful for dealing with errors
|
.BR longjmp ()
|
||||||
and interrupts encountered in a low-level subroutine of a program.
|
performs the transfer of execution.
|
||||||
.BR setjmp ()
|
|
||||||
saves the stack context/environment in
|
|
||||||
.I env
|
|
||||||
for
|
|
||||||
later use by
|
|
||||||
.BR longjmp (3).
|
|
||||||
|
|
||||||
If the function which called
|
The
|
||||||
.BR setjmp ()
|
.BR setjmp ()
|
||||||
returns before
|
function saves various information about the calling environment
|
||||||
.BR longjmp (3)
|
(typically, the stack pointer, the instruction pointer,
|
||||||
is called, the behavior is undefined.
|
possibly the values of other registers and the signal mask)
|
||||||
(Some kind of chaos will result.)
|
in the buffer
|
||||||
.P
|
.IR env
|
||||||
|
for later use by
|
||||||
|
.BR longjmp ().
|
||||||
|
In this case,
|
||||||
|
.BR setjmp ()
|
||||||
|
returns 0.
|
||||||
|
|
||||||
|
The
|
||||||
|
.BR longjmp ()
|
||||||
|
function uses the information saved in
|
||||||
|
.IR env
|
||||||
|
to transfer control back to the point where
|
||||||
|
.BR setjmp ()
|
||||||
|
was called and to restore ("rewind") the stack to its state at the time of the
|
||||||
|
.BR 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
|
||||||
|
.BR setjmp ()
|
||||||
|
call.
|
||||||
|
|
||||||
|
Following a successful
|
||||||
|
.BR longjmp (),
|
||||||
|
execution continues as if
|
||||||
|
.BR setjmp ()
|
||||||
|
had returned for a second time.
|
||||||
|
This "fake" return can be distinguished from a true
|
||||||
|
.BR setjmp ()
|
||||||
|
call because the "fake" return returns the value provided in
|
||||||
|
.IR val .
|
||||||
|
If the programmer mistakenly passes the value 0 in
|
||||||
|
.IR val ,
|
||||||
|
the "fake" return will instead return 1.
|
||||||
|
|
||||||
|
.SS sigsetjmp() and siglongjmp()
|
||||||
.BR sigsetjmp ()
|
.BR sigsetjmp ()
|
||||||
is similar to
|
and
|
||||||
.BR setjmp ().
|
.BR siglongjmp ()
|
||||||
If, and only if,
|
also perform nonlocal gotos, but provide predictable handling of
|
||||||
|
the process signal mask.
|
||||||
|
|
||||||
|
If, and only if, the
|
||||||
.I savesigs
|
.I savesigs
|
||||||
is nonzero,
|
argument provided to
|
||||||
the process's current signal mask is saved in
|
.BR sigsetjmp ()
|
||||||
|
is nonzero, the process's current signal mask is saved in
|
||||||
.I env
|
.I env
|
||||||
and will be restored if a
|
and will be restored if a
|
||||||
.BR siglongjmp (3)
|
.BR siglongjmp ()
|
||||||
is later performed with this
|
is later performed with this
|
||||||
.IR env .
|
.IR env .
|
||||||
.SH RETURN VALUE
|
.SH RETURN VALUE
|
||||||
.BR setjmp ()
|
.BR setjmp ()
|
||||||
and
|
and
|
||||||
.BR sigsetjmp ()
|
.BR sigsetjmp ()
|
||||||
return 0 if returning directly, and
|
return 0 when called directly;
|
||||||
nonzero when returning from
|
on the "fake" return that occurs after
|
||||||
.BR longjmp (3)
|
.BR longjmp ()
|
||||||
or
|
or
|
||||||
.BR siglongjmp (3)
|
.BR siglongjmp (),
|
||||||
using the saved context.
|
the nonzero value specified in
|
||||||
|
.I val
|
||||||
|
is returned.
|
||||||
|
|
||||||
|
The
|
||||||
|
.BR longjmp ()
|
||||||
|
or
|
||||||
|
.BR siglongjmp ()
|
||||||
|
functions do not return.
|
||||||
.SH ATTRIBUTES
|
.SH ATTRIBUTES
|
||||||
For an explanation of the terms used in this section, see
|
For an explanation of the terms used in this section, see
|
||||||
.BR attributes (7).
|
.BR attributes (7).
|
||||||
.TS
|
.TS
|
||||||
allbox;
|
allbox;
|
||||||
lbw21 lb lb
|
lbw23 lb lb
|
||||||
l l l.
|
l l l.
|
||||||
Interface Attribute Value
|
Interface Attribute Value
|
||||||
T{
|
T{
|
||||||
.BR setjmp (),
|
.BR setjmp (),
|
||||||
.BR sigsetjmp ()
|
.BR sigsetjmp ()
|
||||||
T} Thread safety MT-Safe
|
T} Thread safety MT-Safe
|
||||||
|
T{
|
||||||
|
.BR longjmp (),
|
||||||
|
.BR siglongjmp ()
|
||||||
|
T} Thread safety MT-Safe
|
||||||
.TE
|
.TE
|
||||||
|
|
||||||
.SH CONFORMING TO
|
.SH CONFORMING TO
|
||||||
.BR setjmp ():
|
.BR setjmp (),
|
||||||
|
.BR longjmp ():
|
||||||
POSIX.1-2001, POSIX.1-2008, C89, C99.
|
POSIX.1-2001, POSIX.1-2008, C89, C99.
|
||||||
|
|
||||||
.BR sigsetjmp ():
|
.BR sigsetjmp (),
|
||||||
|
.BR siglongjmp ():
|
||||||
POSIX.1-2001, POSIX.1-2008.
|
POSIX.1-2001, POSIX.1-2008.
|
||||||
.SH NOTES
|
.SH NOTES
|
||||||
POSIX does not specify whether
|
POSIX does not specify whether
|
||||||
.BR setjmp ()
|
.BR setjmp ()
|
||||||
will save the signal mask
|
will save the signal mask
|
||||||
(to be later restored during
|
(to be later restored during
|
||||||
.BR longjmp (3)).
|
.BR longjmp ().
|
||||||
In System V it will not.
|
In System V it will not.
|
||||||
In 4.3BSD it will, and there
|
In 4.3BSD it will, and there
|
||||||
is a function
|
is a function
|
||||||
|
@ -145,32 +199,100 @@ with a nonzero
|
||||||
.I savesigs
|
.I savesigs
|
||||||
argument.
|
argument.
|
||||||
|
|
||||||
If you want to portably save and restore signal masks, use
|
.BR setjmp ()
|
||||||
|
and
|
||||||
|
.BR 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
|
||||||
.BR sigsetjmp ()
|
.BR sigsetjmp ()
|
||||||
and
|
and
|
||||||
.BR siglongjmp (3).
|
.BR siglongjmp ().
|
||||||
|
See also the discussion of program readability below.
|
||||||
|
|
||||||
|
The compiler may optimize variables into registers, and
|
||||||
|
.BR 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
|
||||||
|
.BR longjmp ()
|
||||||
|
if they meet all the following criteria:
|
||||||
|
.IP \(bu 3
|
||||||
|
they are local to the function that made the corresponding
|
||||||
|
.BR setjmp (3)
|
||||||
|
call;
|
||||||
|
.IP \(bu
|
||||||
|
their values are changed between the calls to
|
||||||
|
.BR setjmp (3)
|
||||||
|
and
|
||||||
|
.BR longjmp ();
|
||||||
|
and
|
||||||
|
.IP \(bu
|
||||||
|
they are not declared as
|
||||||
|
.IR volatile .
|
||||||
|
.P
|
||||||
|
Analogous remarks apply for
|
||||||
|
.BR siglongjmp ().
|
||||||
|
.\"
|
||||||
|
.SS Nonlocal gotos and program readability
|
||||||
While it can be abused,
|
While it can be abused,
|
||||||
the traditional C "goto" statement at least has the benefit that lexical cues
|
the traditional C "goto" statement at least has the benefit that lexical cues
|
||||||
(the goto statement and the target label)
|
(the goto statement and the target label)
|
||||||
that allow the programmer to easily understand the flow of control.
|
allow the programmer to easily perceive the flow of control.
|
||||||
Nonlocal gotos provide no such cues: multiple
|
Nonlocal gotos provide no such cues: multiple
|
||||||
.BR setjmp (3)
|
.BR setjmp ()
|
||||||
calls might employ the same
|
calls might employ the same
|
||||||
.IR jmp_buf
|
.IR jmp_buf
|
||||||
variable so that the content of the variable may change
|
variable so that the content of the variable may change
|
||||||
over the lifetime of the application.
|
over the lifetime of the application.
|
||||||
Consequently, the programmer may be forced to perform detailed
|
Consequently, the programmer may be forced to perform detailed
|
||||||
reading of the code to determine the dynamic target of a partiicular
|
reading of the code to determine the dynamic target of a particular
|
||||||
.BR longjmp (3)
|
.BR longjmp ()
|
||||||
call.
|
call.
|
||||||
(To make the programmer's life easier, each
|
(To make the programmer's life easier, each
|
||||||
.BR setjmp ()
|
.BR setjmp ()
|
||||||
call should employ a unique
|
call should employ a unique
|
||||||
.IR jmp_buf
|
.IR jmp_buf
|
||||||
variable.)
|
variable.)
|
||||||
In summary, nonlocal gotos can make programs harder to understand and maintain,
|
|
||||||
and an alternative should be used if possible.
|
Adding further difficulty, the
|
||||||
|
.BR setjmp ()
|
||||||
|
and
|
||||||
|
.BR 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.
|
||||||
|
.\"
|
||||||
|
.SS Caveats
|
||||||
|
If the function which called
|
||||||
|
.BR setjmp ()
|
||||||
|
returns before
|
||||||
|
.BR longjmp ()
|
||||||
|
is called, the behavior is undefined.
|
||||||
|
Some kind of subtle or unsubtle chaos is sure to result.
|
||||||
|
|
||||||
|
If, in a multithreaded program, a
|
||||||
|
.BR longjmp ()
|
||||||
|
call employs an
|
||||||
|
.I env
|
||||||
|
buffer that was initialized by a call to
|
||||||
|
.BR setjmp ()
|
||||||
|
in a different thread, the behavior is undefined.
|
||||||
|
.\"
|
||||||
|
.\" The following statement appeared in versions up to POSIX.1-2008 TC1,
|
||||||
|
.\" but is set to be removed in POSIX.1-2008 TC2:
|
||||||
|
.\"
|
||||||
|
.\" According to POSIX.1, if a
|
||||||
|
.\" .BR longjmp ()
|
||||||
|
.\" call is performed from a nested signal handler
|
||||||
|
.\" (i.e., from a handler that was invoked in response to a signal that was
|
||||||
|
.\" generated while another signal was already in the process of being
|
||||||
|
.\" handled), the behavior is undefined.
|
||||||
.SH SEE ALSO
|
.SH SEE ALSO
|
||||||
.BR longjmp (3),
|
.BR signal (7)
|
||||||
.BR siglongjmp (3)
|
|
||||||
|
|
Loading…
Reference in New Issue