3.25. SETJMP/LONGJMP
...
/* return if bits() or decode() tries to read past available input */
if (setjmp(s.env) != 0) /* if came back here via longjmp(), */
err = 2; /* then skip decomp(), return error */
else
err = decomp(&s); /* decompress */
...
/* load at least need bits into val */
val = s->bitbuf;
while (s->bitcnt < need) {
if (s->left == 0) {
s->left = s->infun(s->inhow, &(s->in));
if (s->left == 0) longjmp(s->env, 1); /* out of input */
...
if (s->left == 0) {
s->left = s->infun(s->inhow, &(s->in));
if (s->left == 0) longjmp(s->env, 1); /* out of input */
( zlib/contrib/blast/blast.c )
Call tosetjmp()saves currentPC,SPand other registers intoenvstructure, then it returns 0.
In case of error,longjmp()teleportingyou into the point after right aftersetjmp()call, as ifsetjmp()
call returned non-null value (which was passed tolongjmp()). This reminds asfork()syscall in UNIX.
Now let’s take a look on distilled example:
#include <stdio.h>
#include <setjmp.h>
jmp_buf env;
void f2()
{
printf ("%s() begin\n", FUNCTION);
// something odd happened here
longjmp (env, 1234);
printf ("%s() end\n", FUNCTION);
};
void f1()
{
printf ("%s() begin\n", FUNCTION);
f2();
printf ("%s() end\n", FUNCTION);
};
int main()
{
int err=setjmp(env);
if (err==0)
{
f1();
}
else
{
printf ("Error %d\n", err);
};
};
If we run it, we will see:
f1() begin
f2() begin
Error 1234