2

I wrote a test program to try and understand how to use execvp(), but I keep running into a problem. The relevant part of my code is:

...
printf("execute: 'ls -a'\n"); 
char *args[2];
args[0] = "/bin/ls";
args[1] = "ls";
args[2] = "-a";
...
} else if(pid == 0){ //child process
    if(execvp(*args, args) < 0) { //execute command
        fprintf(stderr, "Error: execution failed\n");
        exit(1);
    }
}
...

Whenever I run, I get an error "/bin/ls: cannot access ls: No such file or directory". which ls tells me /bin/ls so I don't understand what I'm doing wrong. Is it because the executable file isn't in my home directory but rather a projects file?

Tommy K
  • 1,759
  • 3
  • 28
  • 51

3 Answers3

3

A couple of issue here:

args is defined as a 2 element array, but you're putting in 3 elements, so you're writing past the end of the array.

The args array needs to have a NULL pointer as the last element, otherwise execvp won't know when it reaches the end of the argument list.

The first element in args should be the name of the program (this is what shows up in a ps listing), and subsequent elements should be the arguments. The way it is now, you have ls as the second element in the array, meaning it's the first argument to the command /bin/ls. So the ls command tries to find the file named ls in the current directory but can't. This explains the error message you're getting.

With the fixes applied:

...
printf("execute: 'ls -a'\n"); 
char *args[3];
char *path = "/bin/ls";
args[0] = "ls";
args[1] = "-a";
args[2] = NULL;
...
} else if(pid == 0){ //child process
    if(execvp(path, args) < 0) { //execute command
        fprintf(stderr, "Error: execution failed\n");
        exit(1);
    }
}
dbush
  • 205,898
  • 23
  • 218
  • 273
  • Good and correct answer, but I had to read it a couple of times before I picked up on your distinction between the "first element" of `args` and the "first argument" to the exec'ed command. – John Bollinger Sep 17 '15 at 16:06
  • @JohnBollinger Thanks, I made some clarifications. – dbush Sep 17 '15 at 16:09
1

Same question as here C - error when attempting to pass /bin/ls to execvp

You basically must terminate the array of pointers with a NULL pointer.

Community
  • 1
  • 1
Ólafur Aron
  • 352
  • 2
  • 12
1

I really think the code is

char *args[3];
args[0] = "/bin/ls";
args[1] = "-a";
args[2] = NULL;

Than

char *args[2];
args[0] = "/bin/ls";
args[1] = "ls";
args[2] = "-a";
asio_guy
  • 3,667
  • 2
  • 19
  • 35