/* The <setjmp.h> header relates to the C phenomenon known as setjmp/longjmp.
* It is used to escape out of the current situation into a previous one.
- * A typical example is in an editor, where hitting DEL breaks off the current
- * command and puts the editor back in the main loop, though care has to be
- * taken when the DEL occurs while executing a library function, since
- * some of them are not reentrant.
*
- * POSIX does not require the process signal mask to be saved and restored
- * during setjmp/longjmp. However, the current implementation does this
- * in order to agree with OSF/1 and other BSD derived systems.
+ * The actual implementations of all these functions and, by extension, parts
+ * of this header, are both compiler- and architecture-dependent. Currently
+ * two compilers are supported: ACK and GCC. Each of these has their own
+ * implementation of the functions in their runtime system library code.
+ * As it is impossible to predict the requirements for any other compilers,
+ * this header may not be compatible with such other compilers either.
*
- * The pair of functions _setjmp/_longjmp may be used when the signal
- * mask is not to be saved/restored. These functions are traditional
- * in BSD systems.
+ * The ACK compiler will not enregister any variables inside a function
+ * containing a setjmp call, even if those variables are explicitly declared
+ * as register variables. Thus for ACK, of all the registers, only the
+ * program counter, stack pointer and frame pointer have to be saved into the
+ * jmp_buf structure. This makes the jmp_buf structure very small, and
+ * moreover, the implementation of the setjmp/longjmp calls (written in EM)
+ * architecture-independent and thus very portable. The ACK compiler
+ * recognizes only the symbol __setjmp as being such a setjmp call.
*
- * There are different ways of implementing setjmp/longjmp. Probably
- * the best way is to unify it with signal handling. This is true for the
- * following reasons: Both setjmp/longjmp and signal delivery must save
- * a context so that it may be restored later. The jmp_buf necessarily
- * contains signal information, namely the signal mask to restore. Both
- * longjmp and the return of a signal handler must trap to the operating
- * system to restore the previous signal mask. Finally, the jmp_buf
- * and the sigcontext structure contain the registers to restore.
+ * The GCC compiler recognizes all of the setjmp/_setjmp/__setjmp name
+ * variants as calls to setjmp functions, and treats them as special
+ * accordingly, but does require that the setjmp implementation save and
+ * restore most of the registers. It has no portable setjmp and longjmp
+ * functions like ACK, and therefore has to have enough space in the jmp_buf
+ * structure to store the registers on any architecture it's ported to.
*
- * Some compilers, namely ACK, will not enregister any variables inside a
- * function containing a call to setjmp, even if those variables are
- * explicitly declared as register variables. Thus for ACK, the
- * identification of the jmp_buf with a sigcontext structure would cause
- * unnecessary overhead: the jmp_buf has room for all the registers, but
- * the only registers that need to be saved are the stack pointer,
- * frame pointer, and program counter.
+ * Taking the common denominator of both compilers, the function definitions
+ * in this header rely on the presence of merely two functions: __setjmp and
+ * longjmp. On the other hand, the size of jmp_buf depends on the compiler
+ * used: for ACK, jmp_buf is exactly big enough to store the three mentioned
+ * registers; for GCC and any other compiler, the size is chosen in such a
+ * way that it's likely to offer enough room to store registers for any
+ * architecture. The POSIX sigjmp_buf is identical to jmp_buf in all cases.
*
- * So, for ACK a jmp_buf is much smaller than a sigcontext structure, and
- * longjmp does not directly call sigreturn. Instead, longjmp calls a
- * front-end function which initializes the appropriate fields of a
- * sigcontext structure, marks this structure as containing no valid
- * general purpose registers, and then calls sigreturn.
+ * As far as porting is concerned --
*
- * The POSIX sigjmp_buf is identical to the jmp_buf in all cases.
+ * All code writers/porters that have to deal with the actual contents of the
+ * jmp_buf structure in one way or another, should look at <sys/jmp_buf.h>.
*
- * Different compilers have different symbols that they recognize as
- * setjmp symbols. ACK recognizes __setjmp, the GNU C compiler
- * recognizes setjmp and _setjmp, and BCC recognizes all three.
- * When these symbols occur within a function, the compiler may keep
- * all local variables on the stack, avoid certain optimizations, or
- * pass hidden arguments to the setjmp function.
- *
- * Thus, setjmp implementations vary in two independent ways which may
- * be identified through the following preprocessor tokens:
+ * Porters of a new compiler to Minix have to make sure the compiler
+ * recognizes at least __setjmp as a setjmp call (if applicable) and provide
+ * library implementations of __setjmp and longjmp conforming to their
+ * declarations below; if this is not possible, compiler-specific code will
+ * have to be added to this header.
*
- * _SETJMP_SYMBOL -- If 0, this means the compiler treats setjmp and _setjmp
- * specially. If 1, this means the compiler treats __setjmp specially.
- *
- * _SETJMP_SAVES_REGS -- If 1, this means setjmp/longjmp must explicitly
- * save and restore all registers. This also implies that a jmp_buf is
- * different than a sigcontext structure. If 0, this means that the compiler
- * will not use register variables within a function that calls one of
- * its SETJMP_SYMBOLs.
- *
- * When _SETJMP_SYMBOL = 1, the implementation has a few dozen bytes of
- * unnecessary overhead. This happens in the following manner: a program uses
- * _setjmp/_longjmp because it is not interested in saving and restoring the
- * signal mask. Nevertheless, because _setjmp expands to the general purpose
- * function __setjmp, code for sigprocmask(2) is linked into the program.
+ * Porters of Minix+GCC to other architectures have to make sure that the
+ * __regs array of the jmp_buf structure is large enough to hold all the
+ * registers the __setjmp implementation for that architecture has to save.
*/
#ifndef _SETJMP_H
#include <ansi.h>
#endif
-#if !defined(__ACK__) && !defined(__BCC__) && !defined(__GNUC__)
-#define __ACK__
-#endif
-
-#ifdef __ACK__
-#define _SETJMP_SYMBOL 1
-#define _SETJMP_SAVES_REGS 0
-#endif
-#ifdef __BCC__
-#define _SETJMP_SYMBOL 0
-#define _SETJMP_SAVES_REGS 1
-#endif
-#ifdef __GNUC__
-#define _SETJMP_SYMBOL 1
-#define _SETJMP_SAVES_REGS 1
-#endif
-
-/* The jmp_buf data type. Do not change the order of these fields -- some
- * C library code refers to these fields by name. When _SETJMP_SAVES_REGS
- * is 1, the file <sys/jmp_buf.h> gives the usage of the sixteen registers.
- */
typedef struct {
- int __flags; /* XXX - long might give better alignment */
- long __mask; /* must have size >= sizeof(sigset_t) */
-#if (_SETJMP_SAVES_REGS == 0)
+#if defined(__ACK__)
_PROTOTYPE(void (*__pc),(void)); /* program counter */
void *__sp; /* stack pointer */
void *__lb; /* local base (ACKspeak for frame pointer) */
-#else
- void *__regs[16]; /* size is machine dependent */
+ long __mask; /* must have size >= sizeof(sigset_t) */
+ int __flags;
+#else /* GCC */
+ int __flags; /* XXX - long might give better alignment */
+ long __mask; /* must have size >= sizeof(sigset_t) */
+ void *__regs[16]; /* actual use is architecture dependent */
#endif
} jmp_buf[1];
-#if (_SETJMP_SYMBOL == 1)
-
_PROTOTYPE( int __setjmp, (jmp_buf _env, int _savemask) );
_PROTOTYPE( void longjmp, (jmp_buf _env, int _val) );
-_PROTOTYPE(int sigjmp, (jmp_buf _jb, int _retval) );
#define setjmp(env) __setjmp((env), 1)
#ifdef _MINIX
#define _setjmp(env) __setjmp((env), 0)
-_PROTOTYPE(void _longjmp, (jmp_buf _env, int _val) );
+#define _longjmp(env, val) longjmp((env), (val))
#endif
#ifdef _POSIX_SOURCE
typedef jmp_buf sigjmp_buf;
-#ifdef __GNUC__
-#define siglongjmp longjmp
-#else
-_PROTOTYPE( void siglongjmp, (sigjmp_buf _env, int _val) );
-#endif
-
#define sigsetjmp(env, savemask) __setjmp((env), (savemask))
+#define siglongjmp(env, val) longjmp((env), (val))
#endif /* _POSIX_SOURCE */
-#endif /* _SETJMP_SYMBOL == 1 */
-
-#if (_SETJMP_SYMBOL == 0)
-
-_PROTOTYPE( int setjmp, (jmp_buf _env) );
-_PROTOTYPE( void longjmp, (jmp_buf _env, int _val) );
-
-#ifdef _MINIX
-_PROTOTYPE( int _setjmp, (jmp_buf _env) );
-_PROTOTYPE( void _longjmp, (jmp_buf _env, int _val) );
-#endif
-
-#ifdef _POSIX_SOURCE
-#define sigjmp_buf jmp_buf
-_PROTOTYPE( void siglongjmp, (sigjmp_buf _env, int _val) );
-/* XXX - the name _setjmp is no good - that's why ACK used __setjmp. */
-#define sigsetjmp(env, savemask) ((savemask) ? setjmp(env) : _setjmp(env))
-#endif /* _POSIX_SOURCE */
-
-#endif /* _SETJMP_SYMBOL == 0 */
-
#endif /* _SETJMP_H */
--- /dev/null
+.TH SETJMP 3 "June 22, 2006"
+.UC 4
+.SH NAME
+setjmp, longjmp, _setjmp, _longjmp, sigsetjmp, siglongjmp \- save and restore execution contexts
+.SH SYNOPSIS
+.nf
+.ft B
+#include <setjmp.h>
+
+int setjmp(jmp_buf env);
+void longjmp(jmp_buf env, int val);
+
+int _setjmp(jmp_buf env);
+void _longjmp(jmp_buf env, int val);
+
+#define _POSIX_SOURCE
+int sigsetjmp(sigjmp_buf env, int savemask);
+void siglongjmp(sigjmp_buf env, int val);
+.SH DESCRIPTION
+These calls provide a way for a process to save an execution context into a
+buffer, and later resume execution from that context, effectively performing
+a non-local jump. The
+.B setjmp
+family of functions store the context into the \fIenv\fP data structure,
+and return the value 0. The
+.B longjmp
+family of functions jump to the context saved in the given \fIenv\fP data
+structure, causing the process to continue as if it returned from the
+corresponding
+.B setjmp
+call again, but this time with the non-zero return value in \fIval\fP.
+.PP
+The difference between the three pairs of setjmp/longjmp functions lies in the
+behaviour with respect to saving/restoring the process signal mask. POSIX does
+not require the process signal mask to be saved and restored during
+.B setjmp
+/
+.B longjmp
+\. However, the current implementation does this in order to agree with OSF/1
+and other BSD derived systems.
+.PP
+The pair of functions
+.B _setjmp
+/
+.B _longjmp
+, traditional in BSD systems, may be used when the signal mask is not to be
+saved/restored.
+.PP
+Finally, the POSIX
+.B sigsetjmp
+/
+.B siglongjmp
+functions allow the programmer to specify explicitly whether the signal mask
+is to be saved/restored, by means of the \fIsavemask\fP parameter. If this
+parameter is zero, the signal mask will not be saved/restored, otherwise it
+will.
+.SH NOTES
+After the function calling
+.B setjmp
+has returned, the saved context may not be used in a call to
+.B longjmp
+anymore, since the relevant portion of the stack may already have been wiped
+out at that point.
+.PP
+Using these functions to return to a previous state from a signal handler
+is possible but should be done with extreme care, as some interrupted library
+routines may not be reentrant and/or temporarily allocate resources.
+.PP
+See the setjmp.h header file for more implementation details specific to Minix.