Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between exec, execvp, execl, execv?

I am writing a code that represent a new shell to Linux. One of the commands I want to support is running a process for example if I get the following line

command [arguments]

Then I want to run command as a process until it finishes running the process.

To do so I know I need to use fork() in order to get the child process and gets it's PID, my problem is that I don't know what is the difference between :

exec, execvp, execl, execv ... and I don't know which one to use and why.

My current code :

void External_Process(char *arguments[MAX_ARG], char* command)
{
    int pID;
    switch(pID = fork())
    {
    case -1:
        perror("fork failed");
        break;
    case 0 :
        setpgrp();

        //execv(command, arguments);
        //execvp(command, arguments);
        //execl("/bin/bash", "/bin/bash","-c",command,NULL);

        printf("smash error: > bad command %s\n" , command);
        exit(-1) ;

        break;

    default:
        return ;
    }
}

Thank you !

like image 845
user7886490 Avatar asked Apr 18 '19 09:04

user7886490


People also ask

What does execv stand for?

execve() is a POSIX (and UNIX systems in general) function of the family of the exec*() functions that replace the current process image. The v comes from the fact that it takes an argument argv to the vector of arguments to the program (the same way the main function of a C program may take it).

What is execl in C?

execl() System Function: In execl() system function takes the path of the executable binary file (i.e. /bin/ls) as the first and second argument. Then, the arguments (i.e. -lh, /home) that you want to pass to the executable followed by NULL. Then execl() system function runs the command and prints the output.

What is the last argument to execl?

The last argument must be (char*)0 , or you have undefined behavior. The first argument is the path of the executable. The following arguments appear in argv of the executed program. The list of these arguments is terminated by a (char*)0 ; that's how the called function knows that the last argument has been reached.

What does Execvp return?

execvp() returns a negative value if the execution fails (e.g., the request file does not exist).


1 Answers

Summary: In your case I would recommend to use execvp.

To find out the differences between the exec* functions you should read the documentation:
https://linux.die.net/man/3/exec
https://linux.die.net/man/2/execve

The difference between execl* and execv* is the argument passing. execl* require a list of arguments while execv* require a vector of arguments.
A list of arguments is useful if you know all the arguments at compile time. In your case the arguments will be entered by the user and you have to construct a vector of arguments at run time, so you should use one of the execv* functions.

The functions with suffix p use the PATH environment variable to find the program (e.g. "ls"), without this you have to specify the full path (either absolute or relative to the current directory, e.g. "/bin/ls"). Using PATH is what shells normally do, so this seems to be the correct choice for you.

The functions with suffix e allow to specify the environment for the process. For simplicity I would not use this in your case.

This leads to the conclusion: execvp

Of course you could also use system (instead of fork/exec*/wait*) as mentioned in vladxjohn's answer, but in this case you would merely use a shell to interpret your command instead of implementing a basic shell.

like image 199
Bodo Avatar answered Sep 28 '22 09:09

Bodo