C Tutorial: Playing with processes

Running a new process: exec

The fork system call creates a new process but that process contains, and is executing, exactly the same code that the parent process has. More often than not, we'd like to run a new program. The execve system call replaces the current process with a new program. The syntox of execve is:

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

This system call returns only if the named program could not run.

argv is the argument list that is passed to the main function of the program, which is the function that is called when any program starts. The last item on the list is 0 (to mark the end of the list). The first, argv[0], is essentially ignored and expected to contain the command name. The program that is executed may use it to find out its name.

filename contains the fill pathname of the program to load and run; for example, "/bin/ls". This is what the operating system tries to load.

envp contains character strings representing the environment in the form name=value. envp is also stored in the global variable char **environ (getenv is a library function to search the environment for the value of a particular name).

Example

This is a small program that overrites itself with another program. The program first prints a message stating that it will run the ls program and then execute:

ls -aF /

As soon as execve is called, the process is overritten with the new program (/bin/ls) and the program's main function gets run.

/* execve: run a program */ /* Paul Krzyzanowski */ #include <stdlib.h> /* needed to define exit() */ #include <unistd.h> /* needed to define getpid() */ #include <stdio.h> /* needed for printf() */ int main(int argc, char **argv) { char *args[] = {"ls", "-aF", "/", 0}; /* each element represents a command line argument */ char *env[] = { 0 }; /* leave the environment list null */ printf("About to run /bin/ls\n"); execve("/bin/ls", args, env); perror("execve"); /* if we get here, execve failed */ exit(1); }

Download this file

Save this file by control-clicking or right clicking the download link and then saving it as execve.c.

Compile this program via:

gcc -o execve execve.c

If you don't have gcc, You may need to substitute the gcc command with cc or another name of your compiler.

Run the program:

./execve

Try replacing the "/bin/ls" string in the first argument to execve with a nonexistent file and see what happens.

Variations on exec

In addition to the execve syatem call, there are a number of library routines that are front-ends to execve. You will usually fine these more convenient than execve. They are described in the execl manual page. There are six of these functions. A couple of useful ones are execlp and execvp.

execlp

execlp, which allows you to specify all the arguments as parameters to the function. Note that the first parameter is the command. The second parameter is the first argument in the argument list that is passed to the program (argv[0]). These are often the same but don't have to be. The last parameter must be a null pointer.A execlp uses the search path set by the PATH environment variable to find the command. For example,

execlp("ls", "ls", "-aF", "/", (char *)0);

/* execlp: run a program using execlp */ /* Paul Krzyzanowski */ #include <stdlib.h> /* needed to define exit() */ #include <unistd.h> /* needed to define getpid() */ #include <stdio.h> /* needed for printf() */ int main(int argc, char **argv) { printf("About to run ls\n"); execlp("ls", "ls", "-aF", "/", (char*)0); perror("execlp"); /* if we get here, execlp failed */ exit(1); }

Download this file

Save this file by control-clicking or right clicking the download link and then saving it as execlp.c.

Compile this program via:

gcc -o execlp execlp.c

Run the program:

./execlp

execvp

The function execvp is almost like the system call execve except that the PATH environment variable is used as a search path for the command and the default environment is used, so you don't have to worry about passing the environment or searching for the command. Here’s an example:

char **av[] = { "ls", "-al", "/usr/paul", (char *)0}; execvp("ls", av);

/* execvp: run a program using execvp */ /* Paul Krzyzanowski */ #include <stdlib.h> /* needed to define exit() */ #include <unistd.h> /* needed to define getpid() */ #include <stdio.h> /* needed for printf() */ int main(int argc, char **argv) { char *args[] = {"ls", "-aF", "/", 0}; /* each element represents a command line argument */ printf("About to run ls\n"); execvp("ls", args); perror("execvp"); /* if we get here, execvp failed */ exit(1); }

Download this file

Save this file by control-clicking or right clicking the download link and then saving it as execvp.c.

Compile this program via:

gcc -o execvp execvp.c

Run the program:

./execvp

Recommended

The Practice of Programming

 

The C Programming Language

 

The UNIX Programming Environment