#include #include #include /* State used in two functions. */ jmp_buf func_state, main_state; /* Random message. */ const char *msg; void func() { /* Meaningless counter. */ int m; /* setjmp() return value. */ int ret; /* This copies the registers to func_state, and returns 0. When the register values are restored by longjmp, the PC is changed so this function returns again. It's return value is specified in the longjmp call. */ ret = setjmp(func_state); if(ret == 0) { /* First time setjmp() returns. */ printf("Begin func()\n"); m = 1; longjmp(main_state, 1); } /* We reach here when setjmp() returns as a result of a register restore by longjmp(). Do a bit, depending on the return value sent by the restore, then restore the registers in main_state which will return control there. */ printf("func: ret = %d, m = %d, msg = %s\n", ret, m, msg); if(ret == 1) m *= 2; longjmp(main_state, 1); /* Control never reaches this point. */ printf("func done\n"); } main() { /* Iteration counter */ int n = 0; /* A set of messages to store in rotation. */ const char *msgs[] = { "Moonbat", "Ringworm", "Northstar", "Swamp", "Polarbear", "Snakeoil" }; /* Save our registers in main_state, then, on the original save, call the function. */ if(!setjmp(main_state)) func(); /* On restores from the function, set a message and go back there. Do this 10 times, then stop. */ msg = msgs[n%6]; if(n++ < 10) longjmp(func_state, n%2 + 1); printf("Done\n"); exit(0); } /* Remember this: setjmp() can return any number of times. longjmp() the longjmp call does not return; instead, it makes last setjmp() on the same buffer return again. */