ptg10805159
216 Process Environment Chapter 7
We callsetjmpfrom the location that we want to return to, which in this example
is in themainfunction. In this case,setjmpreturns 0 because we called it directly.In
the call tosetjmp,the argumentenvis of the special typejmp_buf.This data type is
some form of array that is capable of holding all the information required to restorethe
status of the stack to the state when we calllongjmp.Normally,theenvvariable is a
global variable, since we’ll need to reference it from another function.
When we encounter an error — say, in thecmd_addfunction — we calllongjmp
with two arguments. The first is the sameenvthat we used in a call tosetjmp,and the
second,val, is a nonzerovalue that becomes the return value fromsetjmp.The second
argument allows us to use morethan onelongjmpfor eachsetjmp.For example, we
couldlongjmpfromcmd_addwith avalof 1 and also calllongjmpfromget_token
with avalof 2. In themainfunction, the return value fromsetjmpis either 1 or 2, and
we can test this value, if we want, and determine whether thelongjmpwas from
cmd_addorget_token.
Let’s return to the example. Figure7.11shows both themain and cmd_add
functions. (The other two functions,do_lineandget_token,haven’t changed.)
#include "apue.h"
#include <setjmp.h>
#define TOK_ADD 5
jmp_buf jmpbuffer;
int
main(void)
{
char line[MAXLINE];
if (setjmp(jmpbuffer) != 0)
printf("error");
while (fgets(line, MAXLINE, stdin) != NULL)
do_line(line);
exit(0);
}
...
void
cmd_add(void)
{
int token;
token = get_token();
if (token < 0) /* an error has occurred */
longjmp(jmpbuffer, 1);
/* rest of processing for this command */
}
Figure 7.11 Example ofsetjmpandlongjmp