6

When I call execvp, for example execvp(echo, b) where b is an array of arguments for the command a, will changing this array later affect the execvp call made previously? When I try calling execp(echo, b), it ends up printing out (null) instead of the content inside of b. Can anyone point out why and what I have to do to pass the arguments correctly?

Daniel Fischer
  • 181,706
  • 17
  • 308
  • 431
Lucas
  • 1,577
  • 6
  • 18
  • 25

2 Answers2

12

After you call exec() or one if its relatives, your original program doesn't exist anymore. That means nothing in that program can affect anything after the exec() call, since it never runs. Maybe you're not building your arguments array correctly? Here's a quick working example of execvp():

#include <unistd.h>

int main(void)
{
  char *execArgs[] = { "echo", "Hello, World!", NULL };
  execvp("echo", execArgs);

  return 0;
}

From the execvp() man page:

The execv(), execvp(), and execvpe() functions provide an array of pointers to null-terminated strings that represent the argument list available to the new program. The first argument, by convention, should point to the filename associated with the file being executed. The array of pointers must be terminated by a NULL pointer.

A common mistake is to skip the part about "The first argument, by convention, should point to the filename associated with the file being executed." That's the part that makes sure echo gets "echo" as argv[0], which presumably it depends on.

Carl Norum
  • 219,201
  • 40
  • 422
  • 469
  • Instead of using echo, I used another program that essentially prints out everything in its argv array. I always assumed argv[0] would be the name of the command itself (the first param of execv), but in this case after calling execv, argv[0] was not. Rather it was the second param of execv. Can you clarify this? – Lucas Jan 11 '12 at 23:06
  • Well, when you passed the argument list to `execv`, did you set `argv[0]` to the name of the command? The array you pass as the second argument `execvp` *becomes* `argv` in the new program, so you need to set it up the way it would expect it to be. – Carl Norum Jan 11 '12 at 23:10
  • This code breaks const correctness. I would rather write const char* args[]={...}; but the prototype for execvp requires the strings in args to be writable! – user877329 Aug 05 '13 at 12:07
  • Thanks you helped me. Isn't this sort or redundant having to specify the name of the command twice? Is there ever a time the first arugment to execvp would be different to the first element of the second argument to execvp? Why isn't this done automatically and why don't compilers warn about this? – Celeritas Sep 21 '14 at 21:27
0

Remember, that after exec call your program is exchanged by a new one. It's not executing anymore, so any code in the same process after exec call is, in fact, unreachable.

Are you sure that b array is terminated with NULL? The last element must be NULL for exec to work correctly. Also, remember to set your first parameter to "echo" as well (it's argv[0]).

Try

execlp("echo", "echo", "something", NULL);

Btw, execlp is a bit more comfortable to use, you can pass as many parameters as you wish.

Piotr Zierhoffer
  • 5,005
  • 1
  • 38
  • 59
  • From what I understand, execvp takes in the command and the argv array. At the time of the execvp call, both the command and the argv array were not NULL. However, when echo was called it didn't seem to have any arguments. – Lucas Jan 11 '12 at 23:01
  • But the OP is asking about `execvp`. How is your answer going to help? – Carl Norum Jan 11 '12 at 23:04
  • It only another convention of writing the same thing. All these functions are just proxies for execve, afaik. – Piotr Zierhoffer Jan 11 '12 at 23:06
  • The macro `NULL` is allowed to expand to an integral constant expression. Such an expression serves as a pointer in a pointer context. But the trailing argument of a variadic function is not such a context. You need `(char *) 0` or `(char *) NULL`. – Kaz May 19 '12 at 03:59