I am working on a custom shell for a systems programming class. We were instructed to implement the built-in setenv()
and unsetenv()
commands with a hint of check man pages for putenv()
.
My issue is that setenv(char*, char*, int)
and putenv(char*)
do not seem to be working at all. My code for executing a command entered is as follows:
//... skipping past stuff for IO redirection
pid = fork();
if(pid == 0){
//child
if(!strcmp(_simpleCommands[0]->_arguments[0],"printenv")){
//check if command is "printenv"
extern char **environ;
int i;
for(i = 0; environ[i] != NULL; i++){
printf("%s\n",environ[i]);
}
exit(0);
}
if(!strcmp(_simpleCommands[0]->_arguments[0],"setenv")){
//if command is "setenv" get parameters char* A, char* B
char * p = _simpleCommands[0]->_arguments[1];
char * s = _simpleCommands[0]->_arguments[2];
//putenv(char* s) needs to be formatted A=B; A is variable B is value
char param[strlen(p) + strlen(s) + 1];
strcat(param,p);
strcat(param,"=");
strcat(param,s);
putenv(param);
//setenv(p,s,1);
exit(0);
}
if(!strcmp(_simpleCommands[0]->_arguments[0],"unsetenv")){
//remove environment variable
unsetenv(_simpleCommands[0]->_arguments[0]);
exit(0);
}
//execute command
execvp(_simpleCommands[0]->_arguments[0],_simpleCommands->_arguments);
perror("-myshell");
_exit(1);
}
//omitting restore IO defaults...
If I run printenv
it works properly, but if I try to set a new variable using either putenv()
or setenv()
my printenv()
command returns the exact same thing, so it does not appear to be working.
As a side note, the problem may not be with the functions or how I called them, because my shell is executing the commands as though it had to format a wildcard (*
or ?
) which I am not sure should happen.
The difference to the setenv function is that the exact string given as the parameter string is put into the environment. If the user should change the string after the putenv call this will reflect automatically in the environment.
setenv is a built-in function of the C shell (csh). It is used to define the value of environment variables. If setenv is given no arguments, it displays all environment variables and their values. If only VAR is specified, it sets an environment variable of that name to an empty (null) value.
Description. The putenv() function sets the value of an environment variable by altering an existing variable or creating a new one. The varname parameter points to a string of the form var=x, where x is the new value for the environment variable var .
The SETENV command can be used to define an environment variable and assign a value to it. The value of an environment variable can be retrieved from within the SAS session using the SYSGET function during autoexec processing. The command x setenv a/tmp; sets a=/tmp . The command x echo $a; results in the value /tmp.
You appear to be calling fork
unconditionally before examining the command line. But some shell built-in commands need to run in the parent process, so that their effect persists. All the built-ins that manipulate the environment fall in this category.
As an aside, I wouldn't try to use the C library's environment manipulation functions if I were writing a shell. I'd use three-argument main
, copy envp
into a data structure under my full control, and then feed that back into execve
. This is partially because I'm a control freak, and partially because it's nigh-impossible to do anything complicated with setenv
and/or putenv
and not have a memory leak. See this older SO question for gory details.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With