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.
execve()
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
/bin
as 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 variableenviron
to your new environment. Note thatenviron
is now (POSIX 2008) declared in<unistd.h>
, but previously was not declared anywhere.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
ls
in my current directory:then I don't get the 'Oops!' and do get the 'Haha!'.