我正在编写一个模仿真实shell的一些基本功能的shell,并试图在shell中添加environment,以便子进程可以继承父进程环境的副本。
int Execute(char *argList[]) {
int pid;
int wstatus;
int ret;
pid = fork();
if (!pid) {
environ = VTable2Environ();
signal(SIGINT, SIG_DFL);
signal(SIGQUIT, SIG_DFL);
execvp(argList[0], argList);
perror("execvp");
exit(1);
} else if (pid != -1) {
ret = wait(&wstatus);
if (ret == -1) {
perror("wait");
return -1;
} else {
return wstatus;
}
} else {
perror("fork");
return -1;
}
}
函数VTable2Environ()
返回使用malloc分配的char **environ
,并从进程的变量表中复制全局变量。
char **VTable2Environ(){
char **env = malloc(sizeof(Variable) * (varTableSize + 1));
if(!env)return NULL;
int i, j;
for(i = 0, j = 0; i < varTableSize; ++i){
if(varTable[i].scope == GLOBAL){
env[j++] = varTable[i].str;
}
}
env[j] = NULL;
return env;
}
我想避免内存泄漏。根据execve(2(
execve((不会在成功时返回,并且文本、数据、bss和调用进程的堆栈被程序的堆栈覆盖加载。
似乎environ
没有被execve()
覆盖。那么我需要解放它吗?如果是,怎么做?
不需要free
任何东西。如果exec*
成功,则不需要释放内存;如果失败,则在子进程中运行该exit(1)
,该进程首先分配了内存,并且无需释放内存。
另一件事是,您不需要修改原始环境!execvpe
函数接受第三个参数,即char **environ
;您可以使用它在另一个环境中传递。作为奖励,您的路径可能与执行的进程的路径不同。
因此,您可以编写
char **newEnv = VTable2Environ();
execvpe(argList[0], argList, newEnv);