带有列出环境变量的 exec() 函数
exec() function with listing environment variables
此代码用于程序 "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()
函数时,父类的char **environ
会自动用于执行的程序。 (在这里,第二个 fork()
)
所以,结果应该是第一个 "echoall" 程序的环境是:
USER=unknwon
PATH=/tmp
并且,第二个 "echoall" 程序的环境与父程序的环境列表相同。
但是,我的结果显示与第一个 "echoall" 程序的环境列表相同:
USER=unknown
PATH=/tmp
我在 shell 提示符下执行使用 fork()
(不是 "echoall" 程序)的程序。所以第二个 "echoall" 程序应该输出与 shell 相同的环境列表。(因为使用 fork()
的程序也继承了 shell 的环境列表)。
这里有什么问题?
并且,当程序在上面的擦除注释中使用 fork()
(这意味着它显示其环境列表。)时,waitpid()
函数 return -1
,所以我得到错误?为什么会这样?
在 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
此代码用于程序 "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()
函数时,父类的char **environ
会自动用于执行的程序。 (在这里,第二个 fork()
)
所以,结果应该是第一个 "echoall" 程序的环境是:
USER=unknwon
PATH=/tmp
并且,第二个 "echoall" 程序的环境与父程序的环境列表相同。 但是,我的结果显示与第一个 "echoall" 程序的环境列表相同:
USER=unknown
PATH=/tmp
我在 shell 提示符下执行使用 fork()
(不是 "echoall" 程序)的程序。所以第二个 "echoall" 程序应该输出与 shell 相同的环境列表。(因为使用 fork()
的程序也继承了 shell 的环境列表)。
这里有什么问题?
并且,当程序在上面的擦除注释中使用 fork()
(这意味着它显示其环境列表。)时,waitpid()
函数 return -1
,所以我得到错误?为什么会这样?
在 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