Issue
I'm writing a shell that mimics some basic funciton of a real shell, and I'm trying to add environ in my shell so that child process can inherit a copy of parent's 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;
}
}
function VTable2Environ()
returns a char **environ
, which is allocated using malloc, and copying global variable from the process's variable table.
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;
}
I want to avoid memory leak.And according to execve(2)
execve() does not return on success, and the text, data, bss, and stack of the calling process are overwritten by that of the program loaded.
It seems like environ
is not overwritten by execve()
. So do I need to free it? if so, how?
Solution
There is no need to free
anything. If exec*
was successful you do not need to free memory, and if it failed, you're running that exit(1)
in the child process which allocated the memory in the first place, and you do not need to free memory.
Another thing is that you do not need to modify the original environment! The execvpe
function accepts a 3rd argument which is char **environ
; you can use this to pass in another environment. As a bonus your PATH can be different from the executed process' PATH.
Therefore you can write
char **newEnv = VTable2Environ();
execvpe(argList[0], argList, newEnv);
Answered By - Antti Haapala -- Слава Україні Answer Checked By - David Marino (PHPFixing Volunteer)
0 Comments:
Post a Comment
Note: Only a member of this blog may post a comment.