fork/exec/process explorations
This homework concerns two C programs about how fork and exec work. They come from Understanding Unix/Linx Programming, Bruce Molay, Chapter8.
These are brain-teaser-type problems designed to call your attention to certain subtleties. They are available in source code form on the remote unix server. You can bring them to your own linux machine from the remote server (user "public" has password CS78password). Or, if you want to use them on the remote server, they are in /home/public/ from where you can copy them into your home directory.
The files that contain them are
prob8.2.c
prob8.6.c
Also available there, for you to examine or experiment, are the series of 11 programs used in my slides demonstrating the workings of fork and exec. Source code files for these programs reside on the server. Individually, they are there under the same names by which they appear in the slides shown in class: fork1.c, fork2.c,..., fork11.c. Collectively, the same files are consolidated in fork-sourcefiles-process-creation.zip. They sit in /home/public. You can use them either on the server, logging in to your account there to do so and copying them into your home directory. Alternatively, you can transfer them by scp/sftp, as user "public," to a linux computer of your choice elsewhere and work with them there instead. If you download these source files you will want to compile so you can run them. The command to compile would be, for example:
gcc fork2.c -o fork2
and then to run"
./fork2
The summary of the point of these programs is:
| Version | Purpose |
| fork1 | shows fork, demonstrates that 2 processes result |
| fork2 | shows PIDs (process id numbers) of these processes, and that they're distinct |
| fork3 | shows fork's return value to the child copy (zero) and its return value to the parent copy (child's PID) |
| fork4 | shows how to code differentiated behavior via an "if" structure conditioned on fork's return value |
| fork5 | incorporates an exec call in the child |
| fork6 | introduces exit call in child and wait call in parent, to give orderly discipline to their relative timing |
| fork7 | gets the name of the program to be exec'd from the user via the command line |
| fork8 | interactively gets the name of the program to be exec'd by prompting user |
| fork9 | puts the activity inside a loop to extend it to second, third, fourth,... commands |
| fork10 | shows a zombie process |
| fork11 | shows an adopted child, init process as its step-parent after being pre-deceased by its original parent |
You must understand that copying is the way fork( ) births a new process,. The resultant child process is genetically identical to the parent process, the one that issued the fork( ) call. That is, the child has the same content as the parent (data, buffers, variables, data structures expressing resource usage, even code). Review my presentations (links entitled "Processes," "Homemade shell" "Process miscellany") and Molay's chapter 8 whose source code is available from Molay's website. To figure out 8.4, see the short discussion of file pointers on pages 63-64.
The exercise for you to perform:
Run each of the two programs. Observe the results. Identify what is noteworthy, unexpected, or the supposed point in each of these programs (its behavior of interest). On a piece of paper, for each, write a one or two sentence explanation of what you've identified. In other words, state what the point is and explain. Hand in the paper.
For prob8.2.c what the Molay book asks of the student is, "Predict the output of this program. How would the output change if the two lines with comments were removed?"
For prob8.6.c what the book asks is, "Unix shells allow users to run programs in the background. How is this program similar to a background process?
Here is the source code for the two programs:
prob8.2.c
main()
{
int n;
for (n=0;n<10;n++)
{
printf("my pid = %d, my ppid = %d, n = %d\n" , getpid(), getppid(), n);
sleep(1);
if ( fork() != 0 ) /* what if these two */
exit(0);
/* lines were removed? */
}
}
prob8.6.c
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
main()
{
int i;
if ( fork() != 0 )
exit(0);
for( i=1 ; i<=10 ; i++ )
{
printf("still here..\n");
sleep(i);
}
return 0;
}