Help on use of setjmp(), longjmp()
John A. Weeks III
john at newave.UUCP
Sat Apr 27 12:43:30 AEST 1991
In article <215 at daily-planet.concordia.ca> agostino at concour.cs.concordia.ca (Agostino Deligia) writes:
> Could anyone out there e-mail me an example on how to use setjmp() and
> longjmp() to return from a low-level function to an upper-level function?
> I read the man pages for setjmp()/longjmp(), but the code fragment they
> give doesn't help much. Also, the only book on C that I have doesn't cover
> setjmp()/longjmp().
I'll say--I had to see them work before I caught on. An example can be
found in the book "UNIX Programming Environment" by Kernighan and Pike.
This book, often refered to as K&P, is a must have for anyone with interest
in UNIX and C. Another good book is Using C On The UNIX System by the
Nutshell people (O'Reilly & Associates).
Think of the setjmp() procedure this way. When your program executes it,
it sort of appears to do nothing. But when you call longjmp() later on,
your program appears to start executing as if the setjmp() procedure was
just called. It acts like a goto.
Setjmp() does actually do something when it is called. It saves some
facts about your program. This information is needed so the program can
pick up running at the setjmp() when your longjmp() is called. It needs
a program storage area called a jmp_buf. It stores things like register
values and the stack pointer.
The real trick is how does your program know if you are returning from
setjmp() because you called setjmp(), or because you called longjmp()?
The return value of setjmp() lets you know. If you call setjmp(), it
returns 0. If longjmp() is called, an integer passed as the second
parameter to longjmp() is returned by setjmp().
Why would you want to use setjmp()? I think that it is pretty ugly, just
another type of goto, but I like to use it in my error traping code.
Often you want to exit() when you get an error, but sometimes you need
to do some type of clean-up work. You can longjmp() back somewhere and
do whatever you need to do in a central location.
Here is an example:
jmp_buf retbuf;
main()
{
/* do some stuff */
if ( setjmp( retbuf ) == 0 )
{
someproc()
}
else
printf( "exit on some error\n" );
exit( 0 );
}
void someproc( void )
{
/* do some stuff */
if ( some_type_of_error() )
longjmp( retbuf, 1 );
/* do some more stuff */
}
When main() executes, setjmp is called the first time. It returns zero,
so the someproc() routine is called. If someproc() does not call longjmp,
it will return and the exit is executed. If someproc() calls the longjmp,
setjmp will return nonzero, and the program will pick up executing the
printf, then exit. Pure black magic!
-john-
--
=============================================================================
John A. Weeks III (612) 942-6969 john at newave.mn.org
NeWave Communications ...uunet!tcnet!wd0gol!newave!john
More information about the Comp.lang.c
mailing list