I am trying to use execve to run the ls command. Currently I’m running it with the following arguments:
execve(args[0], args, env_args)
//args looks like {"ls", "-l", "-a", NULL}
//env_args looks like {"PATH=/bin", "USER=me", NULL}
What I expected this to do was run the ls command using my new env_args meaning that it would look up ls in my PATH. However, this code actually doesn’t do anything and when I run the code it just returns to my command prompt without output.
Using the same args[] I was using execvp and ls worked and searched my current path.
Can you tell me what I am doing wrong?
What I am trying to do is write my own shell program where I can create and export my own environment and have exec use the environment I have defined in a char**. Essentially I am writing my own functions to operate on env_args to add and remove vars and when I call exec i want to be able to call exec on {“ls”, “-l”, NULL} and have it look down my new environments path variable for a valid program called ls. I hope this explains what I am doing a little better. I don’t think the extern environ var will work for me in this case.
The
execve()function does not look at PATH; for that, you needexecvp(). Your program was failing to executels, and apparently you don’t report failures to execute a program after theexecve(). Note that members of theexec*()family of functions only return on error.You’d get the result you expected (more or less) if you ran the program with
/binas your current directory (because./ls– akals– would then exist).You need to provide the pathname of the executable in the first argument to
execve(), after finding it using an appropriate PATH setting.Or continue to use
execvp(), but set the variableenvironto your new environment. Note thatenvironis unique among POSIX global variables in that is it not declared in any header.You don’t need to save the old value and restore it; you’re in the child process and switching its environment won’t affect the main program (shell).
This seems to work as I’d expect – and demonstrates that the original code behaves as I’d expect.
I get an ‘Oops!’ followed by the listing of my directory. When I create an executable
lsin my current directory:then I don’t get the ‘Oops!’ and do get the ‘Haha!’.