2016-03-04 70 views
0

该代码可用于程序 “echoall” 功能:EXEC()的上市环境变量

#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()函数没有收到环境列表参数,父母的char **environ自动用于执行程序。 (在这里,第二fork()

所以,结果应该是第一个“echoall”计划的环境是:

USER=unknwon PATH=/tmp

和,第二个“echoall”计划的环境是一样的父母的环境名单。 但是,我的结果显示同样为先“echoall”程序的环境清单:

USER=unknown PATH=/tmp

我执行它在shell提示符下使用fork()(不是“echoall”计划)项目。所以第二个“echoall”程序应该输出与shell相同的环境列表(因为使用fork()的程序也继承了shell的环境列表)。

这里有什么问题?

而且,还当程序在上面擦评论(这意味着它显示了它的环境的列表。)中,waitpid()函数返回-1使用fork(),所以我得到的错误?为什么会发生?

回答

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