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操作, 只是第一次有效.

posted @ 2016-01-02 20:05  zhanglong71  阅读(258)  评论(0编辑  收藏  举报