Why do we pass the command name twice to execve, as a path and in the argument list?
Asked Answered
T

3

8

I have a program written by my professor that prints the working directory (pwd) by using execve(), but I don't understand the parameters.

pid_t pid = fork();

if(pid <0)
   perror(NULL);
else if(pid == 0)
{
   char*argv[] = {"pwd",NULL};
   execve("/bin/pwd",argv,NULL);
   perror(NULL);
}
else
    printf("Im the parent!");
return 0;
}

"/bin/pwd" gives the path to the executable that will be executed.

This means that it will call the pwd function, doesn't it? Then why do I need to have the parameter pwd?

Couldn't the program run without that parameter?

Thalassa answered 25/11, 2019 at 21:28 Comment(0)
C
5

By convention, the first argument passed to a program is the file name of the executable. However, it doesn't necessarily have to be.

As an example, take the following program:

#include <stdio.h>

int main(int argc, char *argv[])
{
    int i;

    printf("number of arguments: %d\n", argc);
    printf("program name: %s\n", argv[0]);
    for (i=1; i<argc; i++) {
        printf("arg %d: %s\n", argv[i]);
    }
    return 0;
}

If you run this program from another like this:

char*argv[] = {"myprog", "A", "B", NULL};
execve("/home/dbush/myprog",argv,NULL);

The above will output:

number of arguments: 3
program name: myprog
arg 1: A
arg 2: B

But you could also run it like this

char*argv[] = {"myotherprog", "A", "B", NULL};
execve("/home/dbush/myprog",argv,NULL);

And it will output:

number of arguments: 3
program name: myotherprog
arg 1: A
arg 2: B

You can use the value of argv[0] as a way to know how your program was called and perhaps expose different functionality based on that.

The popular busybox tool does just this. A single executable is linked with different file names. Depending on which link a user used to run the executable, it can read argv[0] to know whether it was called as ls, ps, pwd, etc.

Certified answered 25/11, 2019 at 21:48 Comment(2)
A good comparison is the HTTP Host header, which does exactly the same thing for websites.Alane
When we issue: pwd it prints the working directory in the following line, but calling /bin/pwd/ in C program prints working directory in first line of terminal.Bibb
C
3

The execve man page has some mention of this. The emphasis is mine.

By convention, the first of these strings should contain the filename associated with the file being executed.

That is, it is not a actually mandatory for the first argv to be the filename. In fact one can test that by changing the argv[0] to any string in the example code and the result will still be correct.

So it really is just a convention. Many programs will use argv[0] and expect it to be the filename. But many programs also do not care about argv[0] (like pwd). So whether argv[0] actually needs to be set to the filename depends on what program is being executed. Having said that, it would be wise to always follow the convention to play nicely with almost everyone's long held expectations.

Conformal answered 25/11, 2019 at 21:47 Comment(0)
D
0

From execve man page: http://man7.org/linux/man-pages/man2/execve.2.html

   argv is an array of argument strings passed to the new program.  By
   convention, the first of these strings (i.e., argv[0]) should contain
   the filename associated with the file being executed.  envp is an
   array of strings, conventionally of the form key=value, which are
   passed as environment to the new program.  The argv and envp arrays
   must each include a null pointer at the end of the array.

So, argv is treated as command line args for new program to execute with. Since by default, for a linux binary invoked with arguments, these args are accessed through argc/argv, where argv[0] holds the program name.

I think this is to keep the behavior parity to match with default case (prog invoked with arguments).

From the source: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/fs/exec.c#l1376

The argv passed to execve is used to construct argv for the about to be launched binary.

Dieldrin answered 25/11, 2019 at 21:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.