exec()函数与列表环境变量

时间:2016-03-04 03:18:49

标签: c linux shell environment

此代码适用于程序" echoall":

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char** argv)
{
        int i;
        char **ptr;
        extern char **environ;

        for(i=0; i<argc; i++)
                printf("argv[%d]: %s \n", i, argv[i]);

        for(ptr=environ; *ptr!=0; ptr++)
        {
                printf("%s \n", *ptr);
        }

        exit(0);
}

此代码适用于使用exec()调用的程序:

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/wait.h>

char *env_init[]={"USER=unknown", "PATH=/tmp", NULL};

int main(void)
{
        //extern char **environ;
        //char **ptr;
        pid_t pid;

        //for(ptr=environ; *ptr!=0; ptr++)
        //      printf("%s\n", *ptr);

        if((pid==fork()) < 0 )
        {
                printf("fork() error");
                exit(1);
        }
        else if(pid==0)
        {
                if(execle("/root/apue/chapter_8/echoall", "echoall", "myarg1", "MY ARG2", (char*)0, env_init)<0)
                {
                        printf("execle() error");
                        exit(1);
                }
        }

        if(waitpid(pid, NULL, 0) < 0)
        {
                printf("wait error");
                exit(1);
        }

        if((pid=fork())<0)
        {
                printf("fork() error");
                exit(1);
        }
        else if(pid==0)
        {
                if(execlp("echoall", "only 1 arg", (char*)0)<0)
                {
                        printf("execlp() error");
                        exit(1);
                }
        }

        exit(0);
}

当我们使用接收环境列表参数的exec()函数时,这些环境列表是已执行程序的环境列表(在此处,第一个fork())。

但是当我们使用不接收环境列表参数的exec()函数时,父{q} char **environ会自动用于执行程序。 (在这里,第二个fork()

所以,结果应该是第一个&#34; echoall&#34;程序的环境是:

USER=unknwon PATH=/tmp

和,第二个&#34; echoall&#34;程序的环境与父母的环境列表相同。 但是,我的结果显示与第一个相同&#34; echoall&#34;程序的环境列表:

USER=unknown PATH=/tmp

我在shell提示符下执行使用fork()(而不是&#34; echoall&#34;程序)的程序。所以第二个&#34; echoall&#34;程序应该输出与shell相同的环境列表。(因为使用fork()的程序也继承了shell的环境列表)。

这里的问题是什么?

而且,当程序在上面的擦除注释上使用fork()时(这意味着它显示了它的环境列表。),waitpid()函数返回-1,所以我收到错误?为什么会这样?

1 个答案:

答案 0 :(得分:2)

在追逐glibc一段时间之后,我终于注意到了gcc一直试图告诉我的事情:

2.c: In function 'main':
2.c:22:16: warning: 'pid' is used uninitialized in this function [-Wuninitialized]
         else if(pid==0)

上面的代码if((pid==fork()) < 0 )应为if ((pid=fork()) < 0)。一旦我改变了,一切都按预期工作......

$ env -i A=1 ./2
argv[0]: echoall 
argv[1]: myarg1 
argv[2]: MY ARG2 
USER=unknown 
PATH=/tmp 

argv[0]: echoall 
argv[1]: only 1 arg 
A=1