Starting a process with the exec() and spawn() calls

Let's look at some of the other process-creation functions.

The next process-creation functions we should look at are the exec() and spawn() families. Before we go into the details, let's see what the differences are between these two groups of functions.

The exec() family transforms the current process into another one. What I mean by that is that when a process issues an exec() function call, that process ceases to run the current program and begins to run another program. The process ID doesn't change—that process changed into another program. What happened to all the threads in the process? We'll come back to that when we look at fork().

The spawn() family, on the other hand, doesn't do that. Calling a member of the spawn() family creates another process (with a new process ID) that corresponds to the program specified in the function's arguments.

Let's look at the different variants of the spawn() and exec() functions. In the table that follows, you'll see which ones are POSIX and which aren't. Of course, for maximum portability, you'll want to use only the POSIX functions. (The spawn() and spawnp() were in a POSIX draft, but never made it into the standard. The POSIX versions are posix_spawn() and posix_spawnp().)

Spawn POSIX? Exec POSIX?
spawn() No
spawnl() No execl() Yes
spawnle() No execle() Yes
spawnlp() No execlp() Yes
spawnlpe() No execlpe() No
spawnp() No
spawnv() No execv() Yes
spawnve() No execve() Yes
spawnvp() No execvp() Yes
spawnvpe() No execvpe() No

While these variants might appear to be overwhelming, there is a pattern to their suffixes:

A suffix of: Means:
l (lowercase “L”) The argument list is specified via a list of parameters given in the call itself, terminated by a NULL argument.
e An environment is specified.
p The PATH environment variable is used in case the full pathname to the program isn't specified.
v The argument list is specified via a pointer to an argument vector.

The argument list is a list of command-line arguments passed to the program.

Also, note that in the C library, spawnlp(), spawnvp(), and spawnlpe() all call spawnvpe(), which in turn calls spawnp(). The functions spawnle(), spawnv(), and spawnl() all eventually call spawnve(), which then calls spawn(). Finally, spawnp() calls spawn(). So, the root of all spawning functionality is the spawn() call.

How the spawn functions are related Figure 1. How the spawn*() functions are related.

Let's now take a look at the various spawn() and exec() variants in detail so that you can get a feel for the various suffixes used. Then, we'll see the spawn() call itself.