您的位置:首页 > 其它

longjmp()/setjmp()跳转

2016-01-02 20:05 411 查看
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操作, 只是第一次有效.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: