Reputation: 17
I'm new to using linux and the bash command line but I was trying to see whether I could execute basic bash commands (or program) from a c file. My code is really simple and I could've sworn that it was working but suddenly it is not acknowledging that the path even exists.
char* arg[] = {"ls", "-l"};
char* environ[] = {"PATH=./", (char*)0};
execve("/bin/ls", arg, environ);/*execute the command 'ls -l' in curdir*/
I've tried to set as PATH=/bin
but it's not even executing the command in that directory. it just returns a similar error.
NOTE: I have tried
char* environ[] = {"PATH=./", NULL};
I've even tried using the envp
from main() and that STILL doesn't work.
Upvotes: 0
Views: 7266
Reputation: 1765
Please always post a complete program.
As said in the man page, and as said in the comments above, you need a NULL
at the end of the arguments list.
You do not need to pass anything in envp[]
since you are running just ls
By convention you should pass the full path of the executable in argv[0]
In short, this works
#include <stdio.h>
#include <unistd.h>
int main(void)
{
char* arg[] = { "/bin/ls", "-l", NULL };
execve("/bin/ls", arg, NULL);
return 0;
}
Upvotes: 1
Reputation: 181008
This error message ...
ls: cannot access 'PATH=./': No such file or directory
... indicates that the ls
utility is attempting to access a file named "PATH=./", which it does not find. That is a manifestation of the undefined behavior arising from your code ...
char* arg[] = {"ls", "-l"}; char* environ[] = {"PATH=./", (char*)0}; execve("/bin/ls", arg, environ);/*execute the command 'ls -l' in curdir*/
... on account of execve()
expecting and relying upon the argument list to which arg
points being terminated by a null pointer.
Although it is somewhat fraught to try to rationalize or interpret undefined behavior, you can imagine that the contents of arrays arg
and environ
are laid out one immediately after the other in memory, so that the combined representation of these two is the same as the representation of a four-element array of char *
. This view is perhaps useful for understanding why the arg
and env
arrays must be terminated by null pointers in the first place.
The fix is to append a null pointer to the value of arg
:
char* arg[] = {"ls", "-l", NULL};
Note also that in this particular case there is no apparent advantage to specifying an environment, so you could simplify by using execv()
instead.
Note, too, that path elements other than /
itself should not contain a trailing /
character. This is not part of a correct name for a directory, and although you can often get away with it, it is poor form.
Upvotes: 3
Reputation: 420
Put NULL in the end of arg array.
char* arg[] = {"ls", "-l", NULL};
The NULL is used to mark the end of the array.
Upvotes: 3