Lezcer
Lezcer

Reputation: 17

ls: cannot access 'PATH=./': No such file or directory

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

Answers (3)

arfneto
arfneto

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

John Bollinger
John Bollinger

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

Arcaniaco
Arcaniaco

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

Related Questions