summaryrefslogtreecommitdiffstats
path: root/man3/setjmp.3
blob: e9f22daf0e6ff07e1607a3e3117cca618d383b15 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
'\" t
.\" Copyright (C) 2016 Michael Kerrisk <mtk.manpages@gmail.com>
.\"
.\" SPDX-License-Identifier: GPL-2.0-or-later
.\"
.TH setjmp 3 2023-02-05 "Linux man-pages 6.03"
.SH NAME
setjmp, sigsetjmp, longjmp, siglongjmp  \- performing a nonlocal goto
.SH LIBRARY
Standard C library
.RI ( libc ", " \-lc )
.SH SYNOPSIS
.nf
.B #include <setjmp.h>
.PP
.BI "int setjmp(jmp_buf " env );
.BI "int sigsetjmp(sigjmp_buf " env ", int " savesigs );
.PP
.BI "[[noreturn]] void longjmp(jmp_buf " env ", int " val );
.BI "[[noreturn]] void siglongjmp(sigjmp_buf " env ", int " val );
.fi
.PP
.RS -4
Feature Test Macro Requirements for glibc (see
.BR feature_test_macros (7)):
.RE
.PP
.BR setjmp ():
see NOTES.
.PP
.BR sigsetjmp ():
.nf
    _POSIX_C_SOURCE
.fi
.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 ()
function dynamically establishes the target to which control
will later be transferred, and
.BR longjmp ()
performs the transfer of execution.
.PP
The
.BR 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
.I env
for later use by
.BR longjmp ().
In this case,
.BR setjmp ()
returns 0.
.PP
The
.BR longjmp ()
function uses the information saved in
.I 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.
.PP
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 ()
and
.BR siglongjmp ()
also perform nonlocal gotos, but provide predictable handling of
the process signal mask.
.PP
If, and only if, the
.I savesigs
argument provided to
.BR sigsetjmp ()
is nonzero, the process's current signal mask is saved in
.I env
and will be restored if a
.BR siglongjmp ()
is later performed with this
.IR env .
.SH RETURN VALUE
.BR setjmp ()
and
.BR sigsetjmp ()
return 0 when called directly;
on the "fake" return that occurs after
.BR longjmp ()
or
.BR siglongjmp (),
the nonzero value specified in
.I val
is returned.
.PP
The
.BR longjmp ()
or
.BR siglongjmp ()
functions do not return.
.SH ATTRIBUTES
For an explanation of the terms used in this section, see
.BR attributes (7).
.ad l
.nh
.TS
allbox;
lbx lb lb
l l l.
Interface	Attribute	Value
T{
.BR setjmp (),
.BR sigsetjmp ()
T}	Thread safety	MT-Safe
T{
.BR longjmp (),
.BR siglongjmp ()
T}	Thread safety	MT-Safe
.TE
.hy
.ad
.sp 1
.SH STANDARDS
.BR setjmp (),
.BR longjmp ():
POSIX.1-2001, POSIX.1-2008, C99.
.PP
.BR sigsetjmp (),
.BR siglongjmp ():
POSIX.1-2001, POSIX.1-2008.
.SH NOTES
POSIX does not specify whether
.BR setjmp ()
will save the signal mask
(to be later restored during
.BR longjmp ()).
In System V it will not.
In 4.3BSD it will, and there
is a function
.BR _setjmp ()
that will not.
The behavior under Linux depends on the glibc version
and the setting of feature test macros.
Before glibc 2.19,
.BR setjmp ()
follows the System V behavior by default,
but the BSD behavior is provided if the
.B _BSD_SOURCE
feature test macro is explicitly defined
.\" so that _FAVOR_BSD is triggered
and none of
.BR _POSIX_SOURCE ,
.BR _POSIX_C_SOURCE ,
.BR _XOPEN_SOURCE ,
.\" .BR _XOPEN_SOURCE_EXTENDED ,
.BR _GNU_SOURCE ,
or
.B _SVID_SOURCE
is defined.
Since glibc 2.19,
.I <setjmp.h>
exposes only the System V version of
.BR setjmp ().
Programs that need the BSD semantics should replace calls to
.BR setjmp ()
with calls to
.BR sigsetjmp ()
with a nonzero
.I savesigs
argument.
.PP
.BR setjmp ()
and
.BR longjmp ()
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 ()
and
.BR siglongjmp ().
See also the discussion of program readability below.
.PP
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 ()
call;
.IP \[bu]
their values are changed between the calls to
.BR setjmp ()
and
.BR longjmp ();
and
.IP \[bu]
they are not declared as
.IR volatile .
.PP
Analogous remarks apply for
.BR siglongjmp ().
.\"
.SS Nonlocal gotos and program readability
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
.BR setjmp ()
calls might employ the same
.I 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
.BR longjmp ()
call.
(To make the programmer's life easier, each
.BR setjmp ()
call should employ a unique
.I jmp_buf
variable.)
.PP
Adding further difficulty, the
.BR setjmp ()
and
.BR longjmp ()
calls may not even be in the same source code module.
.PP
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.
.PP
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.
.PP
POSIX.1-2008 Technical Corrigendum 2 adds
.\" http://austingroupbugs.net/view.php?id=516#c1195
.BR longjmp ()
and
.BR 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
.BR exit (3)
that occur upon a return from the initial call to
.IR 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:
.IP \[bu] 3
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
.IR main ().
.IP \[bu]
Any signal whose handler performs a long jump must be blocked during
.I 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
.IR main ().
.SH SEE ALSO
.BR signal (7),
.BR signal\-safety (7)