2023-12-27 21:59:05 +00:00
|
|
|
#include <sys/wait.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
|
|
|
|
int main() {
|
|
|
|
// The program that will get run. It is similar to the command-line:
|
|
|
|
// echo "Hello, world!"
|
|
|
|
char *const cmdline[] = { "echo", "Hello, world!", NULL };
|
|
|
|
|
|
|
|
// Create a new process that's a clone of this one. The original process is
|
|
|
|
// known as the parent, and the new process is known as the child. The child
|
|
|
|
// process activates in the `fork` call, meaning both the parent and the child
|
|
|
|
// will return from fork and assign a value to the variable `pid`.
|
|
|
|
pid_t pid = fork();
|
|
|
|
|
|
|
|
// When the child process returns from `fork`, the value assigned to `pid`
|
2023-12-27 22:12:07 +00:00
|
|
|
// will be 0. In the parent process, `pid` will be the process ID (a non-0
|
2024-03-04 18:44:22 +00:00
|
|
|
// number) of the child process. It is important to note that the process ID
|
|
|
|
// of the child isn't actually 0. The call to `fork` only returns 0 to
|
|
|
|
// allow code to determine if it is the child.
|
2023-12-27 21:59:05 +00:00
|
|
|
if(pid == 0) {
|
2024-03-04 18:44:22 +00:00
|
|
|
// Since this block only executes if `pid` is 0, the call to `execvp` will
|
|
|
|
// only be run by the child process. This is done because the `exec` family
|
|
|
|
// of functions replace the process' instructions with the instructions
|
2023-12-27 21:59:05 +00:00
|
|
|
// found in `cmdline[0]` (in this case, `echo`). The `v` in `execvp` means
|
|
|
|
// vector, which in this case refers to the array `cmdline`. The `p` means
|
|
|
|
// path, indicating that it will search all of the directories found in the
|
|
|
|
// environment vaiable `PATH` for the program (in this case, `execvp` is
|
|
|
|
// searching the directories for `echo`).
|
|
|
|
execvp(cmdline[0], cmdline);
|
|
|
|
} else {
|
|
|
|
// In the parent process, pause until the child process exits. The `wait`
|
2023-12-27 22:12:07 +00:00
|
|
|
// function takes a pointer to an integer that contains information about
|
2023-12-27 21:59:05 +00:00
|
|
|
// how the child process exited. If the exit information isn't necessary,
|
2023-12-27 22:12:07 +00:00
|
|
|
// `NULL` can be passed instead. Several macros are available to obtain
|
|
|
|
// further information about how the process exited.
|
|
|
|
int status = 0;
|
|
|
|
wait(&status);
|
|
|
|
printf("Process %d exited with status %d.\n", pid, status);
|
2023-12-27 21:59:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// The parent process is now finished, and will return the number `0` to
|
|
|
|
// indicate it was successful. The child process will never reach this point
|
|
|
|
// in this program, since its instructions were replaced with `echo`s
|
|
|
|
// instructions earlier.
|
|
|
|
return 0;
|
|
|
|
}
|