So this is basically how a POSIX-XCU shell exectues a program. In reality, a shell with job control especially, has a much more involed procedure. But in brunt of the things, this is how it's done.
A Fork-Exec-Wait loop, hereby refered to as FEWL, has three stages:
1- Fork the parent process 2- Execute the program in the child process 3- Wait until the program terminates in the parent process.
On Linux, and most POSIX systems, programs are created by forking in this exact same manner. Sometimes via a shell using an 'initrc' script, sometime using an explciit FEWL. What this mean is, on POSIX, there's a process tree that begins with the 'mother' process, often called the 'init' proces, and everything is forked from there.
Every process has with itself a PCB --- a 'Process Control Block'. POSIX does not specify what PCB should contain, or how the programmer should access PCB. On Linux, for example, if you include 'linux/sched.h' you will gain access to a data strcucture which contains the PCB for the current process.
When you shut down the system, again, it is not 'fully' specified in POSIX specs, but usually, the process tree is walked back and they are all SIGTERM'd. Notice that SIGTERM is different from SIGINT. SIGINT means 'interrupt', and SIGINT can be issued by any program. But SIGTERM can only be issued by the kernel, or something with elavated access (beyond that of sudo, maybe an LKM? Not sure!)
Save this into a file called fewl.c. Then run gcc -o fewl fewl.c
. After that, you can run it like:
./fewl echo "This echoes"
Then echo
is invoked.
Notice that, in the C runtime library, there are 6 exec*
functions whereas there's only one execve
system call. The runtime function that I have used, execvp
, threats the program (the first argument) like shell treats them, it looks for it the the usual places specified by confstr
library routine. Some exec-family functions do this, some don't. Consult man 3 exec
for more info.