Simplified - C & Linux - Fork & Exec

Processes (Background)

Processes are basically a program which was executed. You double clicked an icon on your desktop? You probably initiated a process. On the develop'ish side of things, we can go deeper into how processes are created and ran.

On Unix-like systems, every process is created and executed by an already running process. The already running process is called the parent, and the created one is his child. These parent-child relations all form a processes tree (type ptree in your terminal for an example). In case you wondered, the first parent is called 'Init' and it's a process that automatically runs on system launch.

Fork & Exec

The C function which creates a new process from a running one, is called fork(). From the line that this function is called, there are 2 running processes of your code, as if you ran the executable twice. Luckily, fork's return value is different for each of the processes, allowing us to conditionalize our code execution for each of them. It returns 0 in the child process, and a PID (process ID number) of the child, in the parent process. A simple example:

pid_t child_pid = fork();

if (0 == child_pid) 
{
   printf("This will be printed by the child process only!\n");
} 
else
{
   printf("This will be printed by the parent process only!\n");
}

note: fork's failure case was discarded for simplicity. Fitting behavior for failure (-1 == child_pid) should be added.

So fork runs a copy of the current process from the line it's called. But what if you want to run a new process? That's what exec is here for. exec is a big family of functions which replaces the current process with a new one. Essentially, we can create a copy of the current process with fork, and then transform it into a new, unrelated process with exec!.

pid_t child_pid = fork();

if (0 == child_pid) 
{
   printf("This is the child process. We will now make it into a new one!\n");
   execvp(file_name, args_for_it);
   printf("This line will never be printed, unless execvp failed!\n");
} 
else
{
   printf("This is the parent process, it will keep running on the current 
           code file.\n");
}

In the example above, we used the function execvp. You can read further about it's arguments online (or in the good ol' man), but it's overall purpose is just as described above. The second printf line won't be printed since once execvp was called, the child process is no longer a copy of it's parent, but a new running process of whichever file we gave it!

Hope you got the simplified basics down! You should be ready to dive deeper into it as necessary.

RwK