Blame manual/setjmp.texi

Packit 6c4009
@node Non-Local Exits, Signal Handling, Resource Usage And Limitation, Top
Packit 6c4009
@c %MENU% Jumping out of nested function calls
Packit 6c4009
@chapter Non-Local Exits
Packit 6c4009
@cindex non-local exits
Packit 6c4009
@cindex long jumps
Packit 6c4009
Packit 6c4009
Sometimes when your program detects an unusual situation inside a deeply
Packit 6c4009
nested set of function calls, you would like to be able to immediately
Packit 6c4009
return to an outer level of control.  This section describes how you can
Packit 6c4009
do such @dfn{non-local exits} using the @code{setjmp} and @code{longjmp}
Packit 6c4009
functions.
Packit 6c4009
Packit 6c4009
@menu
Packit 6c4009
* Intro: Non-Local Intro.        When and how to use these facilities.
Packit 6c4009
* Details: Non-Local Details.    Functions for non-local exits.
Packit 6c4009
* Non-Local Exits and Signals::  Portability issues.
Packit 6c4009
* System V contexts::            Complete context control a la System V.
Packit 6c4009
@end menu
Packit 6c4009
Packit 6c4009
@node Non-Local Intro, Non-Local Details,  , Non-Local Exits
Packit 6c4009
@section Introduction to Non-Local Exits
Packit 6c4009
Packit 6c4009
As an example of a situation where a non-local exit can be useful,
Packit 6c4009
suppose you have an interactive program that has a ``main loop'' that
Packit 6c4009
prompts for and executes commands.  Suppose the ``read'' command reads
Packit 6c4009
input from a file, doing some lexical analysis and parsing of the input
Packit 6c4009
while processing it.  If a low-level input error is detected, it would
Packit 6c4009
be useful to be able to return immediately to the ``main loop'' instead
Packit 6c4009
of having to make each of the lexical analysis, parsing, and processing
Packit 6c4009
phases all have to explicitly deal with error situations initially
Packit 6c4009
detected by nested calls.
Packit 6c4009
Packit 6c4009
(On the other hand, if each of these phases has to do a substantial
Packit 6c4009
amount of cleanup when it exits---such as closing files, deallocating
Packit 6c4009
buffers or other data structures, and the like---then it can be more
Packit 6c4009
appropriate to do a normal return and have each phase do its own
Packit 6c4009
cleanup, because a non-local exit would bypass the intervening phases and
Packit 6c4009
their associated cleanup code entirely.  Alternatively, you could use a
Packit 6c4009
non-local exit but do the cleanup explicitly either before or after
Packit 6c4009
returning to the ``main loop''.)
Packit 6c4009
Packit 6c4009
In some ways, a non-local exit is similar to using the @samp{return}
Packit 6c4009
statement to return from a function.  But while @samp{return} abandons
Packit 6c4009
only a single function call, transferring control back to the point at
Packit 6c4009
which it was called, a non-local exit can potentially abandon many
Packit 6c4009
levels of nested function calls.
Packit 6c4009
Packit 6c4009
You identify return points for non-local exits by calling the function
Packit 6c4009
@code{setjmp}.  This function saves information about the execution
Packit 6c4009
environment in which the call to @code{setjmp} appears in an object of
Packit 6c4009
type @code{jmp_buf}.  Execution of the program continues normally after
Packit 6c4009
the call to @code{setjmp}, but if an exit is later made to this return
Packit 6c4009
point by calling @code{longjmp} with the corresponding @w{@code{jmp_buf}}
Packit 6c4009
object, control is transferred back to the point where @code{setjmp} was
Packit 6c4009
called.  The return value from @code{setjmp} is used to distinguish
Packit 6c4009
between an ordinary return and a return made by a call to
Packit 6c4009
@code{longjmp}, so calls to @code{setjmp} usually appear in an @samp{if}
Packit 6c4009
statement.
Packit 6c4009
Packit 6c4009
Here is how the example program described above might be set up:
Packit 6c4009
Packit 6c4009
@smallexample
Packit 6c4009
@include setjmp.c.texi
Packit 6c4009
@end smallexample
Packit 6c4009
Packit 6c4009
The function @code{abort_to_main_loop} causes an immediate transfer of
Packit 6c4009
control back to the main loop of the program, no matter where it is
Packit 6c4009
called from.
Packit 6c4009
Packit 6c4009
The flow of control inside the @code{main} function may appear a little
Packit 6c4009
mysterious at first, but it is actually a common idiom with
Packit 6c4009
@code{setjmp}.  A normal call to @code{setjmp} returns zero, so the
Packit 6c4009
``else'' clause of the conditional is executed.  If
Packit 6c4009
@code{abort_to_main_loop} is called somewhere within the execution of
Packit 6c4009
@code{do_command}, then it actually appears as if the @emph{same} call
Packit 6c4009
to @code{setjmp} in @code{main} were returning a second time with a value
Packit 6c4009
of @code{-1}.
Packit 6c4009
Packit 6c4009
@need 250
Packit 6c4009
So, the general pattern for using @code{setjmp} looks something like:
Packit 6c4009
Packit 6c4009
@smallexample
Packit 6c4009
if (setjmp (@var{buffer}))
Packit 6c4009
  /* @r{Code to clean up after premature return.} */
Packit 6c4009
  @dots{}
Packit 6c4009
else
Packit 6c4009
  /* @r{Code to be executed normally after setting up the return point.} */
Packit 6c4009
  @dots{}
Packit 6c4009
@end smallexample
Packit 6c4009
Packit 6c4009
@node Non-Local Details, Non-Local Exits and Signals, Non-Local Intro, Non-Local Exits
Packit 6c4009
@section Details of Non-Local Exits
Packit 6c4009
Packit 6c4009
Here are the details on the functions and data structures used for
Packit 6c4009
performing non-local exits.  These facilities are declared in
Packit 6c4009
@file{setjmp.h}.
Packit 6c4009
@pindex setjmp.h
Packit 6c4009
Packit 6c4009
@deftp {Data Type} jmp_buf
Packit 6c4009
@standards{ISO, setjmp.h}
Packit 6c4009
Objects of type @code{jmp_buf} hold the state information to
Packit 6c4009
be restored by a non-local exit.  The contents of a @code{jmp_buf}
Packit 6c4009
identify a specific place to return to.
Packit 6c4009
@end deftp
Packit 6c4009
Packit 6c4009
@deftypefn Macro int setjmp (jmp_buf @var{state})
Packit 6c4009
@standards{ISO, setjmp.h}
Packit 6c4009
@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
Packit 6c4009
@c _setjmp ok
Packit 6c4009
@c  __sigsetjmp(!savemask) ok
Packit 6c4009
@c   __sigjmp_save(!savemask) ok, does not call sigprocmask
Packit 6c4009
When called normally, @code{setjmp} stores information about the
Packit 6c4009
execution state of the program in @var{state} and returns zero.  If
Packit 6c4009
@code{longjmp} is later used to perform a non-local exit to this
Packit 6c4009
@var{state}, @code{setjmp} returns a nonzero value.
Packit 6c4009
@end deftypefn
Packit 6c4009
Packit 6c4009
@deftypefun void longjmp (jmp_buf @var{state}, int @var{value})
Packit 6c4009
@standards{ISO, setjmp.h}
Packit 6c4009
@safety{@prelim{}@mtsafe{}@asunsafe{@ascuplugin{} @asucorrupt{} @asulock{/hurd}}@acunsafe{@acucorrupt{} @aculock{/hurd}}}
Packit 6c4009
@c __libc_siglongjmp @ascuplugin @asucorrupt @asulock/hurd @acucorrupt @aculock/hurd
Packit 6c4009
@c  _longjmp_unwind @ascuplugin @asucorrupt @acucorrupt
Packit 6c4009
@c   __pthread_cleanup_upto @ascuplugin @asucorrupt @acucorrupt
Packit 6c4009
@c     plugins may be unsafe themselves, but even if they weren't, this
Packit 6c4009
@c     function isn't robust WRT async signals and cancellation:
Packit 6c4009
@c     cleanups aren't taken off the stack right away, only after all
Packit 6c4009
@c     cleanups have been run.  This means that async-cancelling
Packit 6c4009
@c     longjmp, or interrupting longjmp with an async signal handler
Packit 6c4009
@c     that calls longjmp may run the same cleanups multiple times.
Packit 6c4009
@c    _JMPBUF_UNWINDS_ADJ ok
Packit 6c4009
@c    *cleanup_buf->__routine @ascuplugin
Packit 6c4009
@c  sigprocmask(SIG_SETMASK) dup @asulock/hurd @aculock/hurd
Packit 6c4009
@c  __longjmp ok
Packit 6c4009
This function restores current execution to the state saved in
Packit 6c4009
@var{state}, and continues execution from the call to @code{setjmp} that
Packit 6c4009
established that return point.  Returning from @code{setjmp} by means of
Packit 6c4009
@code{longjmp} returns the @var{value} argument that was passed to
Packit 6c4009
@code{longjmp}, rather than @code{0}.  (But if @var{value} is given as
Packit 6c4009
@code{0}, @code{setjmp} returns @code{1}).@refill
Packit 6c4009
@end deftypefun
Packit 6c4009
Packit 6c4009
There are a lot of obscure but important restrictions on the use of
Packit 6c4009
@code{setjmp} and @code{longjmp}.  Most of these restrictions are
Packit 6c4009
present because non-local exits require a fair amount of magic on the
Packit 6c4009
part of the C compiler and can interact with other parts of the language
Packit 6c4009
in strange ways.
Packit 6c4009
Packit 6c4009
The @code{setjmp} function is actually a macro without an actual
Packit 6c4009
function definition, so you shouldn't try to @samp{#undef} it or take
Packit 6c4009
its address.  In addition, calls to @code{setjmp} are safe in only the
Packit 6c4009
following contexts:
Packit 6c4009
Packit 6c4009
@itemize @bullet
Packit 6c4009
@item
Packit 6c4009
As the test expression of a selection or iteration
Packit 6c4009
statement (such as @samp{if}, @samp{switch}, or @samp{while}).
Packit 6c4009
Packit 6c4009
@item
Packit 6c4009
As one operand of an equality or comparison operator that appears as the
Packit 6c4009
test expression of a selection or iteration statement.  The other
Packit 6c4009
operand must be an integer constant expression.
Packit 6c4009
Packit 6c4009
@item
Packit 6c4009
As the operand of a unary @samp{!} operator, that appears as the
Packit 6c4009
test expression of a selection or iteration statement.
Packit 6c4009
Packit 6c4009
@item
Packit 6c4009
By itself as an expression statement.
Packit 6c4009
@end itemize
Packit 6c4009
Packit 6c4009
Return points are valid only during the dynamic extent of the function
Packit 6c4009
that called @code{setjmp} to establish them.  If you @code{longjmp} to
Packit 6c4009
a return point that was established in a function that has already
Packit 6c4009
returned, unpredictable and disastrous things are likely to happen.
Packit 6c4009
Packit 6c4009
You should use a nonzero @var{value} argument to @code{longjmp}.  While
Packit 6c4009
@code{longjmp} refuses to pass back a zero argument as the return value
Packit 6c4009
from @code{setjmp}, this is intended as a safety net against accidental
Packit 6c4009
misuse and is not really good programming style.
Packit 6c4009
Packit 6c4009
When you perform a non-local exit, accessible objects generally retain
Packit 6c4009
whatever values they had at the time @code{longjmp} was called.  The
Packit 6c4009
exception is that the values of automatic variables local to the
Packit 6c4009
function containing the @code{setjmp} call that have been changed since
Packit 6c4009
the call to @code{setjmp} are indeterminate, unless you have declared
Packit 6c4009
them @code{volatile}.
Packit 6c4009
Packit 6c4009
@node Non-Local Exits and Signals, System V contexts, Non-Local Details, Non-Local Exits
Packit 6c4009
@section Non-Local Exits and Signals
Packit 6c4009
Packit 6c4009
In BSD Unix systems, @code{setjmp} and @code{longjmp} also save and
Packit 6c4009
restore the set of blocked signals; see @ref{Blocking Signals}.  However,
Packit 6c4009
the POSIX.1 standard requires @code{setjmp} and @code{longjmp} not to
Packit 6c4009
change the set of blocked signals, and provides an additional pair of
Packit 6c4009
functions (@code{sigsetjmp} and @code{siglongjmp}) to get the BSD
Packit 6c4009
behavior.
Packit 6c4009
Packit 6c4009
The behavior of @code{setjmp} and @code{longjmp} in @theglibc{} is
Packit 6c4009
controlled by feature test macros; see @ref{Feature Test Macros}.  The
Packit 6c4009
default in @theglibc{} is the POSIX.1 behavior rather than the BSD
Packit 6c4009
behavior.
Packit 6c4009
Packit 6c4009
The facilities in this section are declared in the header file
Packit 6c4009
@file{setjmp.h}.
Packit 6c4009
@pindex setjmp.h
Packit 6c4009
Packit 6c4009
@deftp {Data Type} sigjmp_buf
Packit 6c4009
@standards{POSIX.1, setjmp.h}
Packit 6c4009
This is similar to @code{jmp_buf}, except that it can also store state
Packit 6c4009
information about the set of blocked signals.
Packit 6c4009
@end deftp
Packit 6c4009
Packit 6c4009
@deftypefun int sigsetjmp (sigjmp_buf @var{state}, int @var{savesigs})
Packit 6c4009
@standards{POSIX.1, setjmp.h}
Packit 6c4009
@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{/hurd}}@acunsafe{@aculock{/hurd}}}
Packit 6c4009
@c sigsetjmp @asulock/hurd @aculock/hurd
Packit 6c4009
@c  __sigsetjmp(savemask) @asulock/hurd @aculock/hurd
Packit 6c4009
@c   __sigjmp_save(savemask) @asulock/hurd @aculock/hurd
Packit 6c4009
@c    sigprocmask(SIG_BLOCK probe) dup @asulock/hurd @aculock/hurd
Packit 6c4009
This is similar to @code{setjmp}.  If @var{savesigs} is nonzero, the set
Packit 6c4009
of blocked signals is saved in @var{state} and will be restored if a
Packit 6c4009
@code{siglongjmp} is later performed with this @var{state}.
Packit 6c4009
@end deftypefun
Packit 6c4009
Packit 6c4009
@deftypefun void siglongjmp (sigjmp_buf @var{state}, int @var{value})
Packit 6c4009
@standards{POSIX.1, setjmp.h}
Packit 6c4009
@safety{@prelim{}@mtsafe{}@asunsafe{@ascuplugin{} @asucorrupt{} @asulock{/hurd}}@acunsafe{@acucorrupt{} @aculock{/hurd}}}
Packit 6c4009
@c Alias to longjmp.
Packit 6c4009
This is similar to @code{longjmp} except for the type of its @var{state}
Packit 6c4009
argument.  If the @code{sigsetjmp} call that set this @var{state} used a
Packit 6c4009
nonzero @var{savesigs} flag, @code{siglongjmp} also restores the set of
Packit 6c4009
blocked signals.
Packit 6c4009
@end deftypefun
Packit 6c4009
Packit 6c4009
@node System V contexts,, Non-Local Exits and Signals, Non-Local Exits
Packit 6c4009
@section Complete Context Control
Packit 6c4009
Packit 6c4009
The Unix standard provides one more set of functions to control the
Packit 6c4009
execution path and these functions are more powerful than those
Packit 6c4009
discussed in this chapter so far.  These functions were part of the
Packit 6c4009
original @w{System V} API and by this route were added to the Unix
Packit 6c4009
API.  Besides on branded Unix implementations these interfaces are not
Packit 6c4009
widely available.  Not all platforms and/or architectures @theglibc{}
Packit 6c4009
is available on provide this interface.  Use @file{configure} to
Packit 6c4009
detect the availability.
Packit 6c4009
Packit 6c4009
Similar to the @code{jmp_buf} and @code{sigjmp_buf} types used for the
Packit 6c4009
variables to contain the state of the @code{longjmp} functions the
Packit 6c4009
interfaces of interest here have an appropriate type as well.  Objects
Packit 6c4009
of this type are normally much larger since more information is
Packit 6c4009
contained.  The type is also used in a few more places as we will see.
Packit 6c4009
The types and functions described in this section are all defined and
Packit 6c4009
declared respectively in the @file{ucontext.h} header file.
Packit 6c4009
Packit 6c4009
@deftp {Data Type} ucontext_t
Packit 6c4009
@standards{SVID, ucontext.h}
Packit 6c4009
Packit 6c4009
The @code{ucontext_t} type is defined as a structure with at least the
Packit 6c4009
following elements:
Packit 6c4009
Packit 6c4009
@table @code
Packit 6c4009
@item ucontext_t *uc_link
Packit 6c4009
This is a pointer to the next context structure which is used if the
Packit 6c4009
context described in the current structure returns.
Packit 6c4009
Packit 6c4009
@item sigset_t uc_sigmask
Packit 6c4009
Set of signals which are blocked when this context is used.
Packit 6c4009
Packit 6c4009
@item stack_t uc_stack
Packit 6c4009
Stack used for this context.  The value need not be (and normally is
Packit 6c4009
not) the stack pointer.  @xref{Signal Stack}.
Packit 6c4009
Packit 6c4009
@item mcontext_t uc_mcontext
Packit 6c4009
This element contains the actual state of the process.  The
Packit 6c4009
@code{mcontext_t} type is also defined in this header but the definition
Packit 6c4009
should be treated as opaque.  Any use of knowledge of the type makes
Packit 6c4009
applications less portable.
Packit 6c4009
Packit 6c4009
@end table
Packit 6c4009
@end deftp
Packit 6c4009
Packit 6c4009
Objects of this type have to be created by the user.  The initialization
Packit 6c4009
and modification happens through one of the following functions:
Packit 6c4009
Packit 6c4009
@deftypefun int getcontext (ucontext_t *@var{ucp})
Packit 6c4009
@standards{SVID, ucontext.h}
Packit 6c4009
@safety{@prelim{}@mtsafe{@mtsrace{:ucp}}@assafe{}@acsafe{}}
Packit 6c4009
@c Linux-only implementations in assembly, including sigprocmask
Packit 6c4009
@c syscall.  A few cases call the sigprocmask function, but that's safe
Packit 6c4009
@c too.  The ppc case is implemented in terms of a swapcontext syscall.
Packit 6c4009
The @code{getcontext} function initializes the variable pointed to by
Packit 6c4009
@var{ucp} with the context of the calling thread.  The context contains
Packit 6c4009
the content of the registers, the signal mask, and the current stack.
Packit 6c4009
Executing the contents would start at the point where the
Packit 6c4009
@code{getcontext} call just returned.
Packit 6c4009
Packit 6c4009
@strong{Compatibility Note:} Depending on the operating system,
Packit 6c4009
information about the current context's stack may be in the
Packit 6c4009
@code{uc_stack} field of @var{ucp}, or it may instead be in
Packit 6c4009
architecture-specific subfields of the @code{uc_mcontext} field.
Packit 6c4009
Packit 6c4009
The function returns @code{0} if successful.  Otherwise it returns
Packit 6c4009
@code{-1} and sets @var{errno} accordingly.
Packit 6c4009
@end deftypefun
Packit 6c4009
Packit 6c4009
The @code{getcontext} function is similar to @code{setjmp} but it does
Packit 6c4009
not provide an indication of whether @code{getcontext} is returning for
Packit 6c4009
the first time or whether an initialized context has just been restored.
Packit 6c4009
If this is necessary the user has to determine this herself.  This must
Packit 6c4009
be done carefully since the context contains registers which might contain
Packit 6c4009
register variables.  This is a good situation to define variables with
Packit 6c4009
@code{volatile}.
Packit 6c4009
Packit 6c4009
Once the context variable is initialized it can be used as is or it can
Packit 6c4009
be modified using the @code{makecontext} function.  The latter is normally
Packit 6c4009
done when implementing co-routines or similar constructs.
Packit 6c4009
Packit 6c4009
@deftypefun void makecontext (ucontext_t *@var{ucp}, void (*@var{func}) (void), int @var{argc}, @dots{})
Packit 6c4009
@standards{SVID, ucontext.h}
Packit 6c4009
@safety{@prelim{}@mtsafe{@mtsrace{:ucp}}@assafe{}@acsafe{}}
Packit 6c4009
@c Linux-only implementations mostly in assembly, nothing unsafe.
Packit 6c4009
Packit 6c4009
The @var{ucp} parameter passed to @code{makecontext} shall be
Packit 6c4009
initialized by a call to @code{getcontext}.  The context will be
Packit 6c4009
modified in a way such that if the context is resumed it will start by
Packit 6c4009
calling the function @code{func} which gets @var{argc} integer arguments
Packit 6c4009
passed.  The integer arguments which are to be passed should follow the
Packit 6c4009
@var{argc} parameter in the call to @code{makecontext}.
Packit 6c4009
Packit 6c4009
Before the call to this function the @code{uc_stack} and @code{uc_link}
Packit 6c4009
element of the @var{ucp} structure should be initialized.  The
Packit 6c4009
@code{uc_stack} element describes the stack which is used for this
Packit 6c4009
context.  No two contexts which are used at the same time should use the
Packit 6c4009
same memory region for a stack.
Packit 6c4009
Packit 6c4009
The @code{uc_link} element of the object pointed to by @var{ucp} should
Packit 6c4009
be a pointer to the context to be executed when the function @var{func}
Packit 6c4009
returns or it should be a null pointer.  See @code{setcontext} for more
Packit 6c4009
information about the exact use.
Packit 6c4009
@end deftypefun
Packit 6c4009
Packit 6c4009
While allocating the memory for the stack one has to be careful.  Most
Packit 6c4009
modern processors keep track of whether a certain memory region is
Packit 6c4009
allowed to contain code which is executed or not.  Data segments and
Packit 6c4009
heap memory are normally not tagged to allow this.  The result is that
Packit 6c4009
programs would fail.  Examples for such code include the calling
Packit 6c4009
sequences the GNU C compiler generates for calls to nested functions.
Packit 6c4009
Safe ways to allocate stacks correctly include using memory on the
Packit 6c4009
original thread's stack or explicitly allocating memory tagged for
Packit 6c4009
execution using (@pxref{Memory-mapped I/O}).
Packit 6c4009
Packit 6c4009
@strong{Compatibility note}: The current Unix standard is very imprecise
Packit 6c4009
about the way the stack is allocated.  All implementations seem to agree
Packit 6c4009
that the @code{uc_stack} element must be used but the values stored in
Packit 6c4009
the elements of the @code{stack_t} value are unclear.  @Theglibc{}
Packit 6c4009
and most other Unix implementations require the @code{ss_sp} value of
Packit 6c4009
the @code{uc_stack} element to point to the base of the memory region
Packit 6c4009
allocated for the stack and the size of the memory region is stored in
Packit 6c4009
@code{ss_size}.  There are implementations out there which require
Packit 6c4009
@code{ss_sp} to be set to the value the stack pointer will have (which
Packit 6c4009
can, depending on the direction the stack grows, be different).  This
Packit 6c4009
difference makes the @code{makecontext} function hard to use and it
Packit 6c4009
requires detection of the platform at compile time.
Packit 6c4009
Packit 6c4009
@deftypefun int setcontext (const ucontext_t *@var{ucp})
Packit 6c4009
@standards{SVID, ucontext.h}
Packit 6c4009
@safety{@prelim{}@mtsafe{@mtsrace{:ucp}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}}
Packit 6c4009
@c Linux-only implementations mostly in assembly.  Some ports use
Packit 6c4009
@c sigreturn or swapcontext syscalls; others restore the signal mask
Packit 6c4009
@c first and then proceed restore other registers in userland, which
Packit 6c4009
@c leaves a window for cancellation or async signals with misaligned or
Packit 6c4009
@c otherwise corrupt stack.  ??? Switching to a different stack, or even
Packit 6c4009
@c to an earlier state on the same stack, may conflict with pthread
Packit 6c4009
@c cleanups.  This is not quite MT-Unsafe, it's a different kind of
Packit 6c4009
@c safety issue.
Packit 6c4009
Packit 6c4009
The @code{setcontext} function restores the context described by
Packit 6c4009
@var{ucp}.  The context is not modified and can be reused as often as
Packit 6c4009
wanted.
Packit 6c4009
Packit 6c4009
If the context was created by @code{getcontext} execution resumes with
Packit 6c4009
the registers filled with the same values and the same stack as if the
Packit 6c4009
@code{getcontext} call just returned.
Packit 6c4009
Packit 6c4009
If the context was modified with a call to @code{makecontext} execution
Packit 6c4009
continues with the function passed to @code{makecontext} which gets the
Packit 6c4009
specified parameters passed.  If this function returns execution is
Packit 6c4009
resumed in the context which was referenced by the @code{uc_link}
Packit 6c4009
element of the context structure passed to @code{makecontext} at the
Packit 6c4009
time of the call.  If @code{uc_link} was a null pointer the application
Packit 6c4009
terminates normally with an exit status value of @code{EXIT_SUCCESS}
Packit 6c4009
(@pxref{Program Termination}).
Packit 6c4009
Packit 6c4009
If the context was created by a call to a signal handler or from any
Packit 6c4009
other source then the behaviour of @code{setcontext} is unspecified.
Packit 6c4009
Packit 6c4009
Since the context contains information about the stack no two threads
Packit 6c4009
should use the same context at the same time.  The result in most cases
Packit 6c4009
would be disastrous.
Packit 6c4009
Packit 6c4009
The @code{setcontext} function does not return unless an error occurred
Packit 6c4009
in which case it returns @code{-1}.
Packit 6c4009
@end deftypefun
Packit 6c4009
Packit 6c4009
The @code{setcontext} function simply replaces the current context with
Packit 6c4009
the one described by the @var{ucp} parameter.  This is often useful but
Packit 6c4009
there are situations where the current context has to be preserved.
Packit 6c4009
Packit 6c4009
@deftypefun int swapcontext (ucontext_t *restrict @var{oucp}, const ucontext_t *restrict @var{ucp})
Packit 6c4009
@standards{SVID, ucontext.h}
Packit 6c4009
@safety{@prelim{}@mtsafe{@mtsrace{:oucp} @mtsrace{:ucp}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}}
Packit 6c4009
@c Linux-only implementations mostly in assembly.  Some ports call or
Packit 6c4009
@c inline getcontext and/or setcontext, adjusting the saved context in
Packit 6c4009
@c between, so we inherit the potential issues of both.
Packit 6c4009
Packit 6c4009
The @code{swapcontext} function is similar to @code{setcontext} but
Packit 6c4009
instead of just replacing the current context the latter is first saved
Packit 6c4009
in the object pointed to by @var{oucp} as if this was a call to
Packit 6c4009
@code{getcontext}.  The saved context would resume after the call to
Packit 6c4009
@code{swapcontext}.
Packit 6c4009
Packit 6c4009
Once the current context is saved the context described in @var{ucp} is
Packit 6c4009
installed and execution continues as described in this context.
Packit 6c4009
Packit 6c4009
If @code{swapcontext} succeeds the function does not return unless the
Packit 6c4009
context @var{oucp} is used without prior modification by
Packit 6c4009
@code{makecontext}.  The return value in this case is @code{0}.  If the
Packit 6c4009
function fails it returns @code{-1} and sets @var{errno} accordingly.
Packit 6c4009
@end deftypefun
Packit 6c4009
Packit 6c4009
@heading Example for SVID Context Handling
Packit 6c4009
Packit 6c4009
The easiest way to use the context handling functions is as a
Packit 6c4009
replacement for @code{setjmp} and @code{longjmp}.  The context contains
Packit 6c4009
on most platforms more information which may lead to fewer surprises
Packit 6c4009
but this also means using these functions is more expensive (besides
Packit 6c4009
being less portable).
Packit 6c4009
Packit 6c4009
@smallexample
Packit 6c4009
int
Packit 6c4009
random_search (int n, int (*fp) (int, ucontext_t *))
Packit 6c4009
@{
Packit 6c4009
  volatile int cnt = 0;
Packit 6c4009
  ucontext_t uc;
Packit 6c4009
Packit 6c4009
  /* @r{Safe current context.}  */
Packit 6c4009
  if (getcontext (&uc) < 0)
Packit 6c4009
    return -1;
Packit 6c4009
Packit 6c4009
  /* @r{If we have not tried @var{n} times try again.}  */
Packit 6c4009
  if (cnt++ < n)
Packit 6c4009
    /* @r{Call the function with a new random number}
Packit 6c4009
       @r{and the context}.  */
Packit 6c4009
    if (fp (rand (), &uc) != 0)
Packit 6c4009
      /* @r{We found what we were looking for.}  */
Packit 6c4009
      return 1;
Packit 6c4009
Packit 6c4009
  /* @r{Not found.}  */
Packit 6c4009
  return 0;
Packit 6c4009
@}
Packit 6c4009
@end smallexample
Packit 6c4009
Packit 6c4009
Using contexts in such a way enables emulating exception handling.  The
Packit 6c4009
search functions passed in the @var{fp} parameter could be very large,
Packit 6c4009
nested, and complex which would make it complicated (or at least would
Packit 6c4009
require a lot of code) to leave the function with an error value which
Packit 6c4009
has to be passed down to the caller.  By using the context it is
Packit 6c4009
possible to leave the search function in one step and allow restarting
Packit 6c4009
the search which also has the nice side effect that it can be
Packit 6c4009
significantly faster.
Packit 6c4009
Packit 6c4009
Something which is harder to implement with @code{setjmp} and
Packit 6c4009
@code{longjmp} is to switch temporarily to a different execution path
Packit 6c4009
and then resume where execution was stopped.
Packit 6c4009
Packit 6c4009
@smallexample
Packit 6c4009
@include swapcontext.c.texi
Packit 6c4009
@end smallexample
Packit 6c4009
Packit 6c4009
This an example how the context functions can be used to implement
Packit 6c4009
co-routines or cooperative multi-threading.  All that has to be done is
Packit 6c4009
to call every once in a while @code{swapcontext} to continue running a
Packit 6c4009
different context.  It is not recommended to do the context switching from
Packit 6c4009
the signal handler directly since leaving the signal handler via
Packit 6c4009
@code{setcontext} if the signal was delivered during code that was not
Packit 6c4009
asynchronous signal safe could lead to problems. Setting a variable in
Packit 6c4009
the signal handler and checking it in the body of the functions which
Packit 6c4009
are executed is a safer approach.  Since @code{swapcontext} is saving the
Packit 6c4009
current context it is possible to have multiple different scheduling points
Packit 6c4009
in the code.  Execution will always resume where it was left.