C execve() parameters [spawn a shell example]

对着背影说爱祢 提交于 2019-11-30 20:30:42

问题


I have to fill the parameters for:

int execve(const char *filename, char *const argv[], char *const envp[]);

If I execute this program:

#include <unistd.h>
int main() {
        char *args[2];
        args[0] = "/bin/sh";
        args[1] = NULL;
        execve(args[0], args, NULL);
}

the shell is spawned correctly as expected.

My problem is that the shell is spawned correctly also if I pass a NULL as second parameter like that:

#include <unistd.h>

int main() {
        char *args[2];
        args[0] = "/bin/sh";
        args[1] = NULL;
        execve(args[0], NULL, NULL);
}

So what's the purpose to use the args vector (with the "/bin/sh" + NULL) as second parameter instead of a NULL?


回答1:


In this line: execve(args[0], NULL, NULL); you are simply using the first element of args array. You could also use something like char* command="/bin/sh". You have to pass something, because that's how execve() was defined. In your case you pass NULL because you don't need to pass anything.

The point of the second argument of execve() is to pass arguments to the command you are spawning. Suppose that instead of shell you simply want to execute ls, you could then pass f.e. these arguments:

#include <unistd.h>
int main() {
        char *args[2];
        args[0] = "/bin/ls";
        args[1] = "-lh";
        execve(args[0], args, NULL);
}

Also, quoting man execve:

argv is an array of argument strings passed to the new program. By convention, the first of these strings 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.




回答2:


If you pass a null pointer as the second, or the third, argument of execve, your program is incorrect according to POSIX; both of these arguments are required to be non-null. (This is not all that clearly stated in the specification of execve, but it's in there.) I am currently typing this on an operating system that treats passing null pointers,

execve("executable", 0, 0);

as equivalent to passing empty arrays, e.g.

execve("executable", (char *[]){0}, (char *[]){0});

but it would not surprise me to learn that other operating systems would fire a segmentation fault or return -1 with errno set to EFAULT or EINVAL.

Passing empty arrays for these arguments is allowed, but the newly executed program will receive zero arguments in argc/argv if the second argument is an empty array, and/or zero environment variables in envp/environ if the third argument is an empty array. Many programs will malfunction under these conditions. For instance, it is very common to see things like

int main(int argc, char **argv)
{
   if (argc != 4) {
     fprintf(stderr, "usage: %s one two three\n", argv[0]);
     return 2;
   }
   // ...
}

where the program implicitly assumes that argv[0] will always be non-null.

So, you should always provide non-empty arrays for both arguments. The usual convention is that if you don't have anything else to do, you use

execve(program, (char *[]){program, 0}, environ);

which supplies the program's own name as argv[0] and no further arguments, and the same set of environment variables you got from your own parent.



来源:https://stackoverflow.com/questions/30149779/c-execve-parameters-spawn-a-shell-example

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!