我爱抄代码-进程

一、展示进程的环境变量列表

 

/* display_env.c

   展示进程的环境变量列表.
*/
#include "tlpi_hdr.h"

extern char **environ;
                /* Or define _GNU_SOURCE to get it from <unistd.h> */

int
main(int argc, char *argv[])
{
    char **ep;

    for (ep = environ; *ep != NULL; ep++)
        puts(*ep);

    exit(EXIT_SUCCESS);
}

二、执行时修改环境变量

执行案例:

./modify_env"GREET=Hello" SHELL=/bin/bash BYE=ciao

输出:
GREET=Hello
SHELL=/bin/bash
执行案例:
 ./modify_env SHELL=/bin/bash BYE=byebye

输出:
SHELL=/bin/bash
GREET=Hello world

modify_env.c

/* modify_env.c
   本文件中的代码只能在linux环境执行
*/
#define _GNU_SOURCE     /* Get various declarations from <stdlib.h> */
#include <stdlib.h>
#include "tlpi_hdr.h"

extern char **environ;

int
main(int argc, char *argv[])
{
    int j;
    char **ep;

    clearenv();         /* 清空所有环境变量 */

    /* 将命令行参数的变量加入env */

    for (j = 1; j < argc; j++)
        if (putenv(argv[j]) != 0)
            errExit("putenv: %s", argv[j]);

    /* 如果GREET对应的env变量不存在,则赋值为hello world */

    if (setenv("GREET", "Hello world", 0) == -1)
        errExit("setenv");

    /* 删除BYE对应的env */

    unsetenv("BYE");

    /* Display current environment */

    for (ep = environ; *ep != NULL; ep++)
        puts(*ep);

    exit(EXIT_SUCCESS);
}

三、跨函数跳转

goto可以在函数内跳转,下面的代码可以跨函数跳转

/* longjmp.c
   展示通过 setjmp()和longjmp()实现跨越函数的跳转.
   属于奇淫巧技的范畴,尽量不要使用
   使用案例:  longjmp
            longjmp x
            longjmp x y
*/
#include <setjmp.h>
#include "tlpi_hdr.h"

//setjmp、longjmp必须使用同一env,所以设为全局变量
static jmp_buf env;

static void f3(void) {
    longjmp(env, 3);
}

static void f2(void) {
    longjmp(env, 2);
}

static void f1(int argc) {
    if (argc == 1)
        longjmp(env, 1);
    if (argc == 2)
        f2();
    if (argc == 3) {
        f3();
    }
}

int
main(int argc, char *argv[]) {
    //setjmp()调用为后续的longjmp()调用执行的跳转确立了跳转目标,该目标正是程序发起setjmp()调用的位置
    switch (setjmp(env)) {
        case 0:     /* setjmp第一次执行返回0,第二次执行时返回由longjmp设置的val值 */
            printf("Calling f1() after initial setjmp()\n");
            f1(argc);               /* Never returns... */
            break;                  /* ... but this is good form */

        case 1:
            printf("We jumped back from f1()\n");
            break;
        case 2:
            printf("We jumped back from f2()\n");
            break;
        case 3:
            printf("We jumped back from f3()\n");
            break;
    }

    exit(EXIT_SUCCESS);
}

 

posted @ 2022-04-19 14:51  Mars.wang  阅读(87)  评论(0编辑  收藏  举报