此代码适用于程序" 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
,所以我收到错误?为什么会这样?
答案 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