longjmp()/setjmp()跳转
longjmp()/setjmp()学习
这两东东是用于函数间跳转的一对接口.
例:
myjmp.c
#include <stdio.h> #include <errno.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <fcntl.h> #include <termios.h> #include <signal.h> #include <setjmp.h> jmp_buf jmp; void func01(char *s) { puts("i'm in func01....\n"); if(strcmp(s,"func01") == 0) longjmp(jmp,3); puts("i'm leaving func01....\n"); } void func02(char *s) { puts("i'm in func02....\n"); if(strcmp(s,"func02") == 0) longjmp(jmp,2); func01(s); puts("i'm leaving func02....\n"); } void func03(char *s) { puts("i'm in func03....\n"); if(strcmp(s,"func03") == 0) longjmp(jmp,1); func02(s); puts("i'm leaving func03....\n"); } int main(int argc,char *argv[]) { int ret; ret = setjmp(jmp); switch(ret) { case 1: puts("return from func03\n"); break; case 2: puts("return from func02\n"); break; case 3: puts("return from func01\n"); break; } char name[100]; printf("now in main, where are you going: "); gets(name); printf("\ngoing to %s...\n\n",name); func03(name); if(strcmp(name,"main") == 0) puts("you are in main now!!!\n"); else printf("there is no %s function!!!\n\n",name); return 0; }
编译链接运行, 输出结果如下:
从输出结果看, 在符合条件并执行longjmp(env, val)后, 跳转到执行setjmp(env)处, 并以val作为返回值. 如果返回0, 表示从setjmp()返回, 如果非0值var, 表示从longjmp(env, var)返回.
另一个与信号有关的跳转接口sigsetjmp()/siglongjmp()使用举例如下:
例2:
myjmp.c
#include <stdio.h> #include <stdlib.h> #include <time.h> #include <sys/stat.h> #include <unistd.h> #include <sys/types.h> #include <errno.h> #include <signal.h> #include <setjmp.h> jmp_buf jmp; void func01(int signum) { printf("[%s - %d]info: i`m in %s\n", __FILE__, __LINE__, __func__); siglongjmp(jmp,1); printf("[%s - %d]info: i`m leaving %s\n", __FILE__, __LINE__, __func__); } void func02(int signum) { printf("[%s - %d]info: i`m in %s\n", __FILE__, __LINE__, __func__); siglongjmp(jmp,2); printf("[%s - %d]info: i`m leaving %s\n", __FILE__, __LINE__, __func__); } int main(int argc, char *argv[]) { signal(SIGINT,func01); signal(SIGWINCH,func02); int ret; ret = sigsetjmp(jmp,0); if(ret == 1) { printf("[%s - %d]info: return from func01...\n", __FILE__, __LINE__); } else if(ret == 2) { printf("[%s - %d]info: return from func02...\n", __FILE__, __LINE__); } getchar(); return 0; }
编译链接运行后.输出结果如下:
注意, 紧接在siglongjmp()后面的语句没有执行. 进入siglongjmp()执行后, 效果上看是从sigsetjmp()返回的.
与longjmp()/setjmp()不同: 多次拖动窗口或按ctrl+c操作, 只是第一次有效.